430 Stimmen

Standardmethode zum Kopieren einer Datei in Java?

Es hat mich schon immer gestört, dass die einzige Möglichkeit, eine Datei in Java zu kopieren, darin besteht, Streams zu öffnen, einen Puffer zu deklarieren, eine Datei einzulesen, sie in einer Schleife zu durchlaufen und sie in die andere Datei zu schreiben. Das Web ist übersät mit ähnlichen, aber dennoch leicht unterschiedlichen Implementierungen dieser Art von Lösung.

Gibt es einen besseren Weg, der innerhalb der Grenzen der Java-Sprache bleibt (d.h. ohne die Ausführung von OS-spezifischen Befehlen)? Vielleicht in einem zuverlässigen Open-Source-Utility-Paket, das zumindest die zugrunde liegende Implementierung verschleiert und eine Ein-Zeilen-Lösung bietet?

1voto

Vinit Shandilya Punkte 1555

Ich bin zwar etwas spät dran, aber hier ist ein Vergleich der Zeit, die das Kopieren einer Datei mit verschiedenen Kopiermethoden dauert. Ich habe die Methoden 10 Mal durchlaufen und einen Durchschnittswert ermittelt. Die Dateiübertragung mit IO-Streams scheint der schlechteste Kandidat zu sein:

Comparison of file transfer using various methods

Hier sind die Methoden:

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);
}

Der einzige Nachteil, den ich bei der Verwendung der NIO-Kanalklasse sehe, ist, dass ich immer noch keine Möglichkeit finde, den Fortschritt beim Kopieren von Zwischendateien anzuzeigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X