Standardowy zwięzły sposób kopiowania pliku w Javie?

Zawsze przeszkadzało mi, że jedynym sposobem kopiowania pliku w Javie jest otwieranie strumieni, deklarowanie bufora, odczytywanie w jednym pliku, zapętlanie go i zapisywanie go w drugiej parze. Sieć jest zaśmiecona podobnymi, ale wciąż nieco innymi implementacjami tego typu rozwiązania.

Czy istnieje lepszy sposób, który pozostaje w granicach języka Java (co oznacza, że ​​nie wymaga wykonywania poleceń specyficznych dla systemu operacyjnego)? Być może w jakimś niezawodnym pakiecie narzędzi open source, który przynajmniej zasłoniłby tę podstawową implementację i zapewniłby rozwiązanie jednego wiersza?

 rob17 cze 2013, 23:54
Jeśli używasz Java 7, użyj zamiast tego Files.copy, zgodnie z zaleceniem @GlenBest:stackoverflow.com/a/16600787/44737
 toolkit20 wrz 2008, 04:04
W Apache Commons może być cośFileUtils, W szczególnościskopiować plik metody.

questionAnswers(16)

QuestionSolution

Jak wspomniano powyżej, zestaw narzędzi Apache Commons IO jest właściwym rozwiązaniemFileUtils.skopiować plik(); poradzi sobie z całym ciężkim liftingiem.

Jako postscript należy zauważyć, że najnowsze wersje FileUtils (takie jak wydanie 2.0.1) dodały użycie NIO do kopiowania plików;NIO może znacznie zwiększyć wydajność kopiowania plików, w dużej mierze dlatego, że procedury NIO odraczają kopiowanie bezpośrednio do systemu operacyjnego / systemu plików zamiast obsługiwać go poprzez odczyt i zapisywanie bajtów przez warstwę Java. Jeśli więc szukasz wydajności, warto sprawdzić, czy używasz najnowszej wersji FileUtils.

 drye01 paź 2008, 14:47
Jest to również bardzo szybkie. Zastąpiłem fragment kodu, który wykonywaliśmy, xCopy, aby skopiować niektóre katalogi i bardzo dobrze zwiększył prędkość. (Użyłem wersji repozytorium)
 delfuego21 wrz 2008, 04:04
Nie mam pojęcia ... Przeszukałem wszystkie źródła informacji publicznej, które mogę znaleźć, i nie ma żadnej wzmianki o możliwej dacie wydania. Strona JIRA pokazuje tylko pięć otwartych problemów, więc może niedługo?
 Peter20 wrz 2008, 05:01
Bardzo pomocne - czy masz wgląd w to, kiedy oficjalne wydanie będzie zawierać te zmiany nio?
 IlDan06 lut 2012, 11:46
Ostrzeżenie dla użytkowników Androida: NIE jest to zawarte w standardowych interfejsach API systemu Android
 Simon Nickerson08 kwi 2011, 12:08
Od grudnia 2010 r. Apache Commons IO jest w wersji 2.0.1, która ma funkcjonalność NIO. Aktualizacja odpowiedzi.
 Peter03 wrz 2009, 01:05
Publiczne wydanie Apache Commons IO nadal na 1.4, grrrrrrr
 rob17 cze 2013, 23:57
Jeśli używasz Java 7 lub nowszej wersji, możesz użyć Files.copy zgodnie z sugestią @GlenBest:stackoverflow.com/a/16600787/44737

Unikałbym używania mega api jak apache commons. Jest to uproszczona operacja i wbudowana w JDK w nowym pakiecie NIO. Było to już powiązane z poprzednią odpowiedzią, ale kluczową metodą w NIO api są nowe funkcje „transferTo” i „transferFrom”.

http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html#transferTo(long,%20long,%20java.nio.channels.WritableByteChannel)

Jeden z połączonych artykułów pokazuje świetny sposób na zintegrowanie tej funkcji z Twoim kodem za pomocą transferu:

public static void copyFile(File sourceFile, File destFile) throws IOException {
    if(!destFile.exists()) {
        destFile.createNewFile();
    }

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(sourceFile).getChannel();
        destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom(source, 0, source.size());
    }
    finally {
        if(source != null) {
            source.close();
        }
        if(destination != null) {
            destination.close();
        }
    }
}

Nauka NIO może być trochę skomplikowana, więc możesz po prostu zaufać temu mechanikowi, zanim wyruszysz i spróbujesz nauczyć się NIO przez noc. Z osobistego doświadczenia może być bardzo trudno się nauczyć, jeśli nie masz doświadczenia i zostałeś wprowadzony do IO za pośrednictwem strumieni java.io.

 Josh20 cze 2013, 01:13
@EJP Już nie rozwijam się w Javie. Możesz mieć rację, więc możesz zaproponować właściwy sposób.
 foz26 sie 2014, 13:39
W systemie Windows Server stwierdzam, że pliki kopiowane w ten sposób z NIO sporadycznie nie mogą być zmieniane ani usuwane, nawet po wywołaniu close () na wszystkim. Uważam, że jest to spowodowane mapowaniem pamięci, które NIO tworzy, wymagając wyrzucania śmieci, jak opisano wten post.
 user20742101 cze 2013, 03:30
Ten kod mapoważny problem. TransferTo () musi być wywołany w pętli. Nie gwarantuje przeniesienia całej żądanej kwoty.
 Peter22 wrz 2008, 19:19
Dzięki, przydatne informacje. Nadal kłóciłbym się o coś takiego jak Apache Commons, zwłaszcza jeśli pod nim nio (poprawnie); zgadzam się jednak, że ważne jest zrozumienie podstawowych zasad.
 Ravi Wallau04 mar 2009, 22:35
Zgadzam się, że ważne jest, aby zrozumieć pochodzenie nio, ale nadal chciałbym korzystać z Jakarta Commons.
 An̲̳̳drew29 cze 2011, 15:48
@Pete nie wygląda jak Apache Commons używa nio do kopiowania plików.
 Mark Renouf28 mar 2011, 01:15
Uważam, że ta zaktualizowana wersja dotyczy tych problemów:gist.github.com/889747
 Anton K.12 sty 2011, 09:48
Niestety istnieją zastrzeżenia. Kiedy skopiowałem plik 1.5 Gb na Windows 7, 32 bit, nie udało się zmapować pliku. Musiałem szukać innego rozwiązania.
 James P.15 sie 2011, 15:23
@ Mark Renouf: Otrzymuję mieszane wyniki z tym kodem. Nie jestem pewien, co się dzieje, ale kopiowane pliki mają czasami zero bajtów.
 Jesse Glick28 sty 2011, 01:41
Trzy możliwe problemy z powyższym kodem: (a) jeśli getChannel zgłasza wyjątek, możesz przeciekać otwarty strumień; (b) w przypadku dużych plików możesz próbować przenieść więcej na raz, niż system operacyjny może obsłużyć; (c) ignorujesz wartość zwracaną przez transferFrom, więc może to być kopiowanie tylko części pliku. Dlatego org.apache.tools.ant.util.ResourceUtils.copyResource jest tak skomplikowany. Zauważ również, że podczas transferu z OK, przenieś się na JDK 1.4 w systemie Linux:bugs.sun.com/bugdatabase/view_bug.do?bug_id=5056395

Teraz w Javie 7 możesz użyć następującej składni try-with-resource:

public static void copyFile( File from, File to ) throws IOException {

    if ( !to.exists() ) { to.createNewFile(); }

    try (
        FileChannel in = new FileInputStream( from ).getChannel();
        FileChannel out = new FileOutputStream( to ).getChannel() ) {

        out.transferFrom( in, 0, in.size() );
    }
}

Albo jeszcze lepiej, można to również osiągnąć za pomocą nowej klasy plików wprowadzonej w Javie 7:

public static void copyFile( File from, File to ) throws IOException {
    Files.copy( from.toPath(), to.toPath() );
}

Dość snazzy, co?

 Pankaj04 gru 2012, 01:36
wydajność mądry, java NIO FileChannel jest lepszy, przeczytaj ten artykułjournaldev.com/861/4-ways-to-copy-file-in-java
 rob18 cze 2013, 19:13
@Scott: Pete poprosił o rozwiązanie jednokreskowe i jesteś tak blisko ... nie trzeba zawijać Files.copy w metodzie copyFile. Po prostu umieściłem Files.copy (Ścieżka z, Ścieżka do) na początku odpowiedzi i wspomnę, że możesz użyć File.toPath (), jeśli masz istniejące obiekty File: Files.copy (fromFile.toPath (), toFile.toPath ())
 user20742101 cze 2013, 03:30
Ten kod mapoważny problem. TransferTo () musi być wywołany w pętli. Nie gwarantuje przeniesienia całej żądanej kwoty.
 ChrisCantrell27 lis 2012, 01:26
Ah dzięki! Nie wiedziałem o nowej klasie „Pliki” ze wszystkimi jej funkcjami pomocniczymi. Ma dokładnie to, czego potrzebuję. Dzięki za przykład.
 Rick Hodgin19 paź 2011, 00:30
To niesamowite, że Java nie dodała takich rzeczy do dziś. Niektóre operacje są absolutnymi podstawami pisania oprogramowania komputerowego. Twórcy oprogramowania Java firmy Oracle mogli nauczyć się czegoś z systemów operacyjnych, sprawdzając, jakie usługi oferują, aby ułatwić nowicjuszom migrację.

W Javie 7 jest to łatwe ...

File src = new File("original.txt");
File target = new File("copy.txt");

Files.copy(src.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
 momomo17 sty 2015, 11:06
To nie działa dla katalogów. Niech to szlag trafi wszystkich. Więcej komunikacji za pomocą interfejsu API powoduje Twoją winę. Ja też się myliłem.
 Kevin Sadler21 cze 2014, 10:18
Jest zwięzły, mniej znaczy więcej. Ich odpowiedzi są dobre i szczegółowe, ale brakowało mi ich podczas przeglądania. Niestety, istnieje wiele odpowiedzi na to pytanie, a wiele z nich jest długich, przestarzałych i skomplikowanych, a dobre odpowiedzi Scotta i Glen zagubiły się w tym (będę udzielał pomocy w tym zakresie). Zastanawiam się, czy moja odpowiedź mogłaby zostać poprawiona przez zmniejszenie jej do trzech linii przez wybicie komunikatu istniejącego () i błędu.
 Uri Agassi20 cze 2014, 21:59
Co twoja odpowiedź dodaje do Scotta lub Glen'a?
 Kevin Sadler21 sty 2015, 13:01
@momo pytanie brzmiało, jak skopiować plik.

Szybko i pracuj ze wszystkimi wersjami Java również Android:

private void copy(final File f1, final File f2) throws IOException {
    f2.createNewFile();

    final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
    final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");

    file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));

    file1.close();
    file2.close();
}
 Rup14 lis 2013, 11:48
Jednak nie wszystkie systemy plików obsługują pliki mapowane w pamięci, i myślę, że jest to stosunkowo drogie w przypadku małych plików.
 user20742119 lip 2014, 11:44
Nie działa z żadną wersją Java wcześniejszą niż 1.4 i nic nie gwarantuje, że pojedynczy zapis jest wystarczający.

Dostępny w standardzie w Javie 7, path.copyTo:http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html http://java.sun.com/docs/books/tutorial/essential/io/copy.html

Nie mogę uwierzyć, że tak długo zajęło im standaryzowanie czegoś tak powszechnego i prostego jak kopiowanie plików :(

 Jesse Glick03 mar 2012, 01:59
Nie ma Path.copyTo; to jest Files.copy.
 samuel owino15 cze 2017, 15:25
Twój link to 404 człowiek

Aby skopiować plik i zapisać go na ścieżce docelowej, możesz użyć poniższej metody.

public void copy(File src, File dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dst);
        try {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}
 John Henckel29 paź 2013, 21:52
Działa z Java 6, bez dodatkowych słoików.
 Solomonoff's Secret07 wrz 2018, 18:55
Ten kod jest nieprawidłowy.InputStream.read może zwrócić 0, nawet jeśli jest więcej danych.InputStream.read zwraca -1, gdy nie ma więcej danych. Zatem pętla powinna się zakończyć, gdy zwraca -1, a nie 0.
 James Wierzba16 kwi 2015, 21:36
Pracował jak urok. Najlepsze rozwiązanie, które nie wymaga bibliotek zewnętrznych i działa na Javie 1.6. Dzięki.
 Rup23 paź 2013, 16:18
To zadziała, ale nie sądzę, żeby było lepiej niż inne odpowiedzi tutaj?
 user20742119 lip 2014, 11:41
@Rup Jest znacznie lepszy niż inne odpowiedzi tutaj, (a)bo działa i (b) ponieważ nie polega na oprogramowaniu innych firm.
 Rup18 maj 2015, 10:59
@EJP Przez „właściwe” miałem na myśli 1) użycie najlepszych dostępnych API, np. nowsze IO, jeśli to możliwe 2) prezentowanie połączeń do Javy w taki sposób, aby można było łatwo rozpoznać, że jest to kopia pliku - np. kanały reprezentujące całe pliki do odczytu i zapisu, jak w innych odpowiedziach tutaj - i przekształć je w pojedyncze wywołanie systemu operacyjnego. Myślę, że to podejście jest tak powolne, jak to tylko możliwe, szczególnie przy małym buforze.
 user20742117 maj 2015, 20:01
@Rup Zgadzam się, że powinna to być funkcja systemu operacyjnego, ale nie mogę zrozumieć żadnego innego komentarza. W części po pierwszym dwukropku brakuje gdzieś czasownika; Nie chciałbym „ufać” nie oczekiwać, że Java przekształci 1k bloków w coś większego, chociaż sam z pewnością użyłbym znacznie większych bloków; Nigdy nie napisałbym aplikacji, która w pierwszej kolejności korzystała z udostępnionych plików; i nie zdaję sobie sprawy, że jakakolwiek biblioteka innej firmy robi coś „właściwego” (cokolwiek masz na myśli) niż ten kod, z wyjątkiem prawdopodobnie użycia większego bufora.
 Rup19 lip 2014, 12:02
@EJP OK, ale nie jest zbyt mądry. Kopiowanie plików powinno być operacją systemu operacyjnego lub systemu plików, a nie operacją aplikacji: Java ma nadzieję wykryć kopię i przekształcić ją w operację systemu operacyjnego, chyba że jawnie odczytuje plik w trakcie jego zatrzymywania. Jeśli nie uważasz, że Java może to zrobić, czy ufasz, że optymalizuje odczyt 1K i zapisuje w większych blokach? A jeśli źródło i miejsce docelowe znajdowały się na zdalnym udziale w wolnej sieci, to najwyraźniej robi to niepotrzebną pracę. Tak, niektóre JAR-y innych firm są głupio duże (Guava!), Ale dodają wiele takich rzeczy jak to.

Jeśli korzystasz z aplikacji internetowej, która już używa Springa i nie chcesz dołączać Apache Commons IO do prostego kopiowania plików, możesz użyćFileCopyUtils ramy Springa.

public static void copyFile(File src, File dst) throws IOException
{
    long p = 0, dp, size;
    FileChannel in = null, out = null;

    try
    {
        if (!dst.exists()) dst.createNewFile();

        in = new FileInputStream(src).getChannel();
        out = new FileOutputStream(dst).getChannel();
        size = in.size();

        while ((dp = out.transferFrom(in, p, size)) > 0)
        {
            p += dp;
        }
    }
    finally {
        try
        {
            if (out != null) out.close();
        }
        finally {
            if (in != null) in.close();
        }
    }
}
 Rup16 sty 2014, 12:41
Więc różnica w porównaniu z najlepszą akceptowaną odpowiedzią jest taka, że ​​masz transfer w pętli?
 user20742119 lip 2014, 11:43
Nawet się nie kompiluje, a wywołanie createNewFile () jest zbędne i marnotrawne.
Metody te są zaprojektowane z myślą o wydajności (integrują się z natywnymi we / wy systemu operacyjnego).Te metody działają z plikami, katalogami i łączami.Każda z dostarczonych opcji może zostać pominięta - są opcjonalne.Klasa użytkowa
package com.yourcompany.nio;

class Files {

    static int copyRecursive(Path source, Path target, boolean prompt, CopyOptions options...) {
        CopyVisitor copyVisitor = new CopyVisitor(source, target, options).copy();
        EnumSet<FileVisitOption> fileVisitOpts;
        if (Arrays.toList(options).contains(java.nio.file.LinkOption.NOFOLLOW_LINKS) {
            fileVisitOpts = EnumSet.noneOf(FileVisitOption.class) 
        } else {
            fileVisitOpts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
        }
        Files.walkFileTree(source[i], fileVisitOpts, Integer.MAX_VALUE, copyVisitor);
    }

    private class CopyVisitor implements FileVisitor<Path>  {
        final Path source;
        final Path target;
        final CopyOptions[] options;

        CopyVisitor(Path source, Path target, CopyOptions options...) {
             this.source = source;  this.target = target;  this.options = options;
        };

        @Override
        FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        // before visiting entries in a directory we copy the directory
        // (okay if directory already exists).
        Path newdir = target.resolve(source.relativize(dir));
        try {
            Files.copy(dir, newdir, options);
        } catch (FileAlreadyExistsException x) {
            // ignore
        } catch (IOException x) {
            System.err.format("Unable to create: %s: %s%n", newdir, x);
            return SKIP_SUBTREE;
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        Path newfile= target.resolve(source.relativize(file));
        try {
            Files.copy(file, newfile, options);
        } catch (IOException x) {
            System.err.format("Unable to copy: %s: %s%n", source, x);
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        // fix up modification time of directory when done
        if (exc == null && Arrays.toList(options).contains(COPY_ATTRIBUTES)) {
            Path newdir = target.resolve(source.relativize(dir));
            try {
                FileTime time = Files.getLastModifiedTime(dir);
                Files.setLastModifiedTime(newdir, time);
            } catch (IOException x) {
                System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
            }
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        if (exc instanceof FileSystemLoopException) {
            System.err.println("cycle detected: " + file);
        } else {
            System.err.format("Unable to copy: %s: %s%n", file, exc);
        }
        return CONTINUE;
    }
}
Kopiowanie katalogu lub pliku
long bytes = java.nio.file.Files.copy( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                 java.nio.file.StandardCopyOption.COPY_ATTRIBUTES,
                 java.nio.file.LinkOption.NOFOLLOW_LINKS);
Przenoszenie katalogu lub pliku
long bytes = java.nio.file.Files.move( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.ATOMIC_MOVE,
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING);
Kopiowanie katalogu lub pliku rekurencyjnie
long bytes = com.yourcompany.nio.Files.copyRecursive( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                 java.nio.file.StandardCopyOption.COPY_ATTRIBUTES
                 java.nio.file.LinkOption.NOFOLLOW_LINKS );
 Stuart Rossiter03 gru 2014, 14:15
Nazwa pakietu dla plików była nieprawidłowa (powinna być java.nio.file not java.nio). Wysłałem do tego edycję; mam nadzieję, że to dobrze!

Biblioteka Google Guava ma równieżmetoda kopiowania:

public static void copy(File from,
                        File to)
                 throws IOException
Kopiuje wszystkie bajty z jednego pliku do drugiego.

Ostrzeżenie: Jeślito reprezentuje istniejący plik, plik zostanie zastąpiony zawartościąfrom. Jeślito ifrom odnoszą się dopodobnie plik, zawartość tego pliku zostanie usunięta.

Parametry:from - plik źródłowyto - plik docelowy

Rzuca: <a href="http://download.oracle.com/javase/6/docs/api/java/io/IOException.html?is-external=true" rel="nofollow noreferrer" title="class or interface in java.io">IOException</a> - jeśli wystąpi błąd we / wy<a href="http://download.oracle.com/javase/6/docs/api/java/lang/IllegalArgumentException.html?is-external=true" rel="nofollow noreferrer" title="class or interface in java.lang">IllegalArgumentException</a> - Jeślifrom.equals(to)

Trzy możliwe problemy z powyższym kodem:

Jeśli getChannel zgłasza wyjątek, możesz przeciekać otwarty strumień.W przypadku dużych plików możesz próbować przenieść więcej na raz, niż system operacyjny może obsłużyć.Ignorujesz wartość zwracaną przez transferFrom, więc może to być kopiowanie tylko części pliku.

Dlategoorg.apache.tools.ant.util.ResourceUtils.copyResource jest tak skomplikowane. Zauważ również, że podczas transferu z OK, prześlij do JDK 1.4 w systemie Linux (patrzIdentyfikator błędu: 5056395) - Jesse Glick Jan

Zauważ, że wszystkie te mechanizmy kopiują tylko zawartość pliku, a nie metadane, takie jak uprawnienia. Więc jeśli miałbyś kopiować lub przenosić wykonywalny plik .sh na Linuksie, nowy plik nie byłby wykonywalny.

Aby naprawdę skopiować lub przenieść plik, tj. Aby uzyskać ten sam rezultat, co kopiowanie z wiersza poleceń, musisz użyć natywnego narzędzia. Skrypt powłoki lub JNI.

Najwyraźniej można to naprawić w java 7 -http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html. Skrzyżowane palce!

Kopia NIO z buforem jest najszybsza zgodnie z moim testem. Zobacz poniższy kod roboczy z mojego projektu testowego pod adresemhttps://github.com/mhisoft/fastcopy

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;


public class test {

private static final int BUFFER = 4096*16;
static final DecimalFormat df = new DecimalFormat("#,###.##");
public static void nioBufferCopy(final File source, final File target )  {
    FileChannel in = null;
    FileChannel out = null;
    double  size=0;
    long overallT1 =  System.currentTimeMillis();

    try {
        in = new FileInputStream(source).getChannel();
        out = new FileOutputStream(target).getChannel();
        size = in.size();
        double size2InKB = size / 1024 ;
        ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER);

        while (in.read(buffer) != -1) {
            buffer.flip();

            while(buffer.hasRemaining()){
                out.write(buffer);
            }

            buffer.clear();
        }
        long overallT2 =  System.currentTimeMillis();
        System.out.println(String.format("Copied %s KB in %s millisecs", df.format(size2InKB),  (overallT2 - overallT1)));
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    finally {
        close(in);
        close(out);
    }
}

private static void close(Closeable closable)  {
    if (closable != null) {
        try {
            closable.close();
        } catch (IOException e) {
            if (FastCopy.debug)
                e.printStackTrace();
        }    
    }
}

}

 aswzen13 paź 2016, 06:44
ładny! ten jest szybki, a nie standardowy java.io strumień .. kopiowanie 10GB tylko w 160 sekund

Oto trzy sposoby łatwego kopiowania plików za pomocą jednej linii kodu!

Java7:

java.nio.file.Files # copy

private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}

Appache Commons IO:

FileUtils # copyFile

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}

Guawa :

Pliki # kopia

private static void copyFileUsingGuava(File source,File dest) throws IOException{
    Files.copy(source,dest);          
}
 Pimp Trizkit16 lut 2016, 22:18
Pierwszy wymaga 3 parametrów.Files.copy używa się tylko 2 parametrówPath doStream. Po prostu dodaj parametrStandardCopyOption.COPY_ATTRIBUTES lubStandardCopyOption.REPLACE_EXISTING dlaPath doPath
 momomo17 sty 2015, 11:07
Pierwszy nie działa dla katalogów. Niech to szlag trafi wszystkich. Więcej komunikacji za pomocą interfejsu API powoduje Twoją winę. Ja też się myliłem.

Trochę późno na imprezę, ale oto porównanie czasu potrzebnego na skopiowanie pliku przy użyciu różnych metod kopiowania plików. Zapętlałem metody 10 razy i wziąłem średnią. Przesyłanie plików za pomocą strumieni IO wydaje się być najgorszym kandydatem:

Oto metody:

private static long fileCopyUsingFileStreams(File fileToCopy, File newFile) throws IOException {
    FileInputStream input = new FileInputStream(fileToCopy);
    FileOutputStream output = new FileOutputStream(newFile);
    byte[] buf = new byte[1024];
    int bytesRead;
    long start = System.currentTimeMillis();
    while ((bytesRead = input.read(buf)) > 0)
    {
        output.write(buf, 0, bytesRead);
    }
    long end = System.currentTimeMillis();

    input.close();
    output.close();

    return (end-start);
}

private static long fileCopyUsingNIOChannelClass(File fileToCopy, File newFile) throws IOException
{
    FileInputStream inputStream = new FileInputStream(fileToCopy);
    FileChannel inChannel = inputStream.getChannel();

    FileOutputStream outputStream = new FileOutputStream(newFile);
    FileChannel outChannel = outputStream.getChannel();

    long start = System.currentTimeMillis();
    inChannel.transferTo(0, fileToCopy.length(), outChannel);
    long end = System.currentTimeMillis();

    inputStream.close();
    outputStream.close();

    return (end-start);
}

private static long fileCopyUsingApacheCommons(File fileToCopy, File newFile) throws IOException
{
    long start = System.currentTimeMillis();
    FileUtils.copyFile(fileToCopy, newFile);
    long end = System.currentTimeMillis();
    return (end-start);
}

private static long fileCopyUsingNIOFilesClass(File fileToCopy, File newFile) throws IOException
{
    Path source = Paths.get(fileToCopy.getPath());
    Path destination = Paths.get(newFile.getPath());
    long start = System.currentTimeMillis();
    Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
    long end = System.currentTimeMillis();

    return (end-start);
}

Jedynym mankamentem, jaki widzę podczas korzystania z klasy kanałów NIO, jest to, że wciąż nie mogę znaleźć sposobu na pokazanie postępu pośredniego kopiowania plików.

yourAnswerToTheQuestion