Standard prägnante Möglichkeit zum Kopieren einer Datei in Java?

Es hat mich 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 zu durchlaufen und in den anderen Steam zu schreiben. Das Web ist übersät mit ähnlichen, aber immer noch leicht unterschiedlichen Implementierungen dieser Art von Lösung.

Gibt es eine bessere Möglichkeit, die innerhalb der Grenzen der Java-Sprache bleibt (dh, es müssen keine betriebssystemspezifischen Befehle ausgeführt werden)? Vielleicht würde das in einem zuverlässigen Open-Source-Dienstprogrammpaket diese zugrunde liegende Implementierung zumindest verschleiern und eine einzeilige Lösung bieten?

 toolkit20. Sept. 2008, 04:04
Es könnte etwas in Apache Commons gebenFileUtilsInsbesondere dieDatei kopieren Methoden.
 rob17. Juni 2013, 23:54
Wenn Sie Java 7 verwenden, verwenden Sie stattdessen Files.copy, wie von @GlenBest empfohlen:stackoverflow.com/a/16600787/44737

Antworten auf die Frage(16)

lgenden Arbeitscode aus einem Testprojekt von mir unterhttps://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. Okt. 2016, 06:44
nett! Dieser ist eher schnell als standard java.io stream .. Kopieren von 10 GB nur in 160 Sekunden
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. Jan. 2014, 12:41
Der Unterschied zu der oben akzeptierten Antwort besteht also darin, dass Sie die transferFrom in einer while-Schleife haben?
 user20742119. Juli 2014, 11:43
Kompiliert nicht einmal und der Aufruf von createNewFile () ist redundant und verschwenderisch.
Diese Methoden sind leistungsgesteuert (sie lassen sich in native E / A des Betriebssystems integrieren).Diese Methoden funktionieren mit Dateien, Verzeichnissen und Links.Jede der mitgelieferten Optionen kann weggelassen werden - sie sind optional.Die Utility-Klasse
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;
    }
}
Kopieren eines Verzeichnisses oder einer Datei
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);
Ein Verzeichnis oder eine Datei verschieben
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);
Ein Verzeichnis oder eine Datei rekursiv kopieren
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. Dez. 2014, 14:15
Der Paketname für Files war falsch (sollte java.nio.file sein, nicht java.nio). Ich habe dafür eine Bearbeitung eingereicht. hoffe das ist ok

Kopiermethode:

public static void copy(File from,
                        File to)
                 throws IOException
Kopiert alle Bytes von einer Datei in eine andere.

Warnung: Obto Stellt eine vorhandene Datei dar, wird diese Datei mit dem Inhalt von überschriebenfrom. Obto undfrom beziehen sich auf diegleich Datei wird der Inhalt dieser Datei gelöscht.

Parameter:from - die Quelldateito - die Zieldatei

Wirft: <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> - wenn ein E / A-Fehler auftritt<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> - obfrom.equals(to)

wie Sie Dateien einfach mit einer einzigen Codezeile kopieren können!

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

Guave :

Dateien # kopieren

private static void copyFileUsingGuava(File source,File dest) throws IOException{
    Files.copy(source,dest);          
}
 momomo17. Jan. 2015, 11:07
Erstens funktioniert man nicht für Verzeichnisse. Verdammt, jeder versteht das falsch. Eher eine API-Kommunikation stört Ihren Fehler. Ich habe es auch falsch verstanden.
 Pimp Trizkit16. Feb. 2016, 22:18
Zunächst benötigt man 3 Parameter.Files.copy Die Verwendung von nur 2 Parametern ist fürPath zuStream. Fügen Sie einfach den Parameter hinzuStandardCopyOption.COPY_ATTRIBUTES oderStandardCopyOption.REPLACE_EXISTING zumPath zuPath

aber hier ist ein Vergleich der Zeit, die zum Kopieren einer Datei mit verschiedenen Dateikopiermethoden benötigt wird. Ich habe die Methoden 10 Mal durchlaufen und einen Durchschnitt genommen. Die Dateiübertragung mit IO-Streams scheint der schlechteste Kandidat zu sein:

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-Channel-Klasse feststellen kann, ist, dass ich immer noch keine Möglichkeit finde, den Fortschritt des Zwischenkopierens von Dateien anzuzeigen.

die bereits Spring verwendet, und Apache Commons IO nicht zum einfachen Kopieren von Dateien verwenden möchten, können Sie diese verwendenFileCopyUtils des Frühlingsrahmens.

enden:

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

Oder, noch besser, dies kann auch mit der neuen in Java 7 eingeführten Klasse Files erreicht werden:

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

Ziemlich pfiffig, was?

 ChrisCantrell27. Nov. 2012, 01:26
Ah danke! Die neue Klasse "Files" mit all ihren Hilfsfunktionen war mir nicht bekannt. Es hat genau das, was ich brauche. Danke für das Beispiel.
 rob18. Juni 2013, 19:13
@Scott: Pete hat nach einer einzeiligen Lösung gefragt und Sie sind so nah dran ... es ist nicht notwendig, Files.copy in eine copyFile-Methode zu packen. Ich würde einfach die Datei Files.copy (Pfad von, Pfad nach) am Anfang Ihrer Antwort einfügen und erwähnen, dass Sie File.toPath () verwenden können, wenn Sie über vorhandene Dateiobjekte verfügen: Files.copy (fromFile.toPath (), toFile.toPath ())
 Rick Hodgin19. Okt. 2011, 00:30
Es ist erstaunlich, dass Java so etwas bis heute noch nicht hinzugefügt hat. Bestimmte Vorgänge sind für das Schreiben von Computersoftware unerlässlich. Die Oracle-Entwickler von Java könnten ein oder zwei Dinge von den Betriebssystemen lernen und prüfen, welche Dienste sie bereitstellen, um die Migration für Neulinge zu vereinfachen.
 user20742101. Juni 2013, 03:30
Dieser Code hat eineHaupt Problem. transferTo () muss in einer Schleife aufgerufen werden. Es kann nicht garantiert werden, dass der gesamte angeforderte Betrag überwiesen wird.
 Pankaj04. Dez. 2012, 01:36
Performance-weise ist Java NIO FileChannel besser, lesen Sie diesen Artikeljournaldev.com/861/4-ways-to-copy-file-in-java

Dies ist eine vereinfachte Operation, die im neuen NIO-Paket in das JDK integriert ist. Es war irgendwie schon in einer vorherigen Antwort verlinkt, aber die Schlüsselmethode in der NIO-API sind die neuen Funktionen "transferTo" und "transferFrom".

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

In einem der verlinkten Artikel erfahren Sie, wie Sie diese Funktion mithilfe von transferFrom in Ihren Code integrieren können:

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

Das Erlernen von NIO kann etwas schwierig sein. Sie sollten sich also auf diese Mechanik verlassen, bevor Sie loslegen und versuchen, NIO über Nacht zu erlernen. Aus persönlicher Erfahrung kann es sehr schwierig sein, etwas zu lernen, wenn Sie nicht über die Erfahrung verfügen und über die java.io-Streams in IO eingeführt wurden.

 foz26. Aug. 2014, 13:39
Unter Windows Server stelle ich fest, dass Dateien, die zeitweise mit NIO kopiert wurden, nicht umbenannt oder gelöscht werden können, auch wenn close () in allen Fällen aufgerufen wurde. Ich glaube, das liegt an den Speicherzuordnungen, die NIO erstellt und die eine Garbage Collection erfordern, wie in beschriebendieser Beitrag.
 James P.15. Aug. 2011, 15:23
@ Mark Renouf: Ich erhalte gemischte Ergebnisse mit diesem Code. Nicht sicher, was passiert, aber kopierte Dateien haben manchmal null Bytes.
 Anton K.12. Jan. 2011, 09:48
Leider gibt es Vorbehalte. Beim Kopieren einer 1,5-Gbit-Datei unter Windows 7 (32 Bit) konnte die Datei nicht zugeordnet werden. Ich musste nach einer anderen Lösung suchen.
 Mark Renouf28. März 2011, 01:15
Ich glaube, diese aktualisierte Version behebt diese Bedenken:gist.github.com/889747
 Ravi Wallau04. März 2009, 22:35
Ich bin damit einverstanden, dass es wichtig ist, die Hintergründe des NIO zu verstehen, aber ich würde trotzdem mit den Jakarta Commons gehen.
 Josh20. Juni 2013, 01:13
@EJP Ich entwickle nicht mehr wirklich in Java. Sie könnten Recht haben, also können Sie gerne den richtigen Weg vorschlagen.
 Jesse Glick28. Jan. 2011, 01:41
Drei mögliche Probleme mit dem obigen Code: (a) Wenn getChannel eine Ausnahme auslöst, kann ein offener Stream verloren gehen. (b) Bei großen Dateien versuchen Sie möglicherweise, mehr auf einmal zu übertragen, als das Betriebssystem verarbeiten kann. (c) Sie ignorieren den Rückgabewert von transferFrom, sodass möglicherweise nur ein Teil der Datei kopiert wird. Aus diesem Grund ist org.apache.tools.ant.util.ResourceUtils.copyResource so kompliziert. Beachten Sie auch, dass transferFrom in JDK 1.4 unter Linux zwar in Ordnung ist, transferTo jedoch abbricht:bugs.sun.com/bugdatabase/view_bug.do?bug_id=5056395
 Peter22. Sept. 2008, 19:19
Danke, nützliche Infos. Ich würde immer noch für so etwas wie Apache Commons argumentieren, besonders wenn es nio (richtig) darunter verwendet; Ich stimme jedoch zu, dass es wichtig ist, die zugrunde liegenden Grundlagen zu verstehen.
 An̲̳̳drew29. Juni 2011, 15:48
@Pete es sieht nicht so aus, als würde Apache Commons nio noch zum Kopieren von Dateien verwenden.
 user20742101. Juni 2013, 03:30
Dieser Code hat eineHaupt Problem. transferTo () muss in einer Schleife aufgerufen werden. Es kann nicht garantiert werden, dass der gesamte angeforderte Betrag überwiesen wird.

http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html http://java.sun.com/docs/books/tutorial/essential/io/copy.html

Ich kann nicht glauben, dass sie so lange gebraucht haben, um etwas so Häufig und Einfaches wie das Kopieren von Dateien zu standardisieren :(

 Jesse Glick03. März 2012, 01:59
Es gibt kein Path.copyTo; es ist Files.copy.
 samuel owino15. Juni 2017, 15:25
Ihr Link ist 404 Mann

dass alle diese Mechanismen nur den Inhalt der Datei kopieren, nicht die Metadaten wie Berechtigungen. Wenn Sie also eine ausführbare SH-Datei unter Linux kopieren oder verschieben, ist die neue Datei nicht ausführbar.

Um eine Datei wirklich zu kopieren oder zu verschieben, dh um dasselbe Ergebnis wie beim Kopieren von einer Befehlszeile zu erzielen, müssen Sie tatsächlich ein natives Tool verwenden. Entweder ein Shell-Skript oder JNI.

Anscheinend könnte dies in Java 7 behoben werden -http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html. Daumen drücken!

Lösung für das Problem

FileUtils.Datei kopieren(); es erledigt das ganze schwere Heben für Sie.

Beachten Sie außerdem, dass neuere Versionen von FileUtils (z. B. die Version 2.0.1) NIO zum Kopieren von Dateien hinzugefügt haben.NIO kann die Leistung beim Kopieren von Dateien erheblich steigernDies liegt zum großen Teil daran, dass die NIO-Routinen das Kopieren direkt in das Betriebssystem / Dateisystem verzögern, anstatt es durch Lesen und Schreiben von Bytes über die Java-Schicht zu handhaben. Wenn Sie also nach Leistung suchen, sollten Sie überprüfen, ob Sie eine aktuelle Version von FileUtils verwenden.

 delfuego21. Sept. 2008, 04:04
Ich habe keine Ahnung ... Ich habe alle öffentlichen Informationen durchsucht, die ich finden kann, und es gibt keinen Hinweis auf ein mögliches Erscheinungsdatum. Die JIRA-Site zeigt jedoch nur fünf offene Probleme, also vielleicht bald?
 drye01. Okt. 2008, 14:47
Dies ist auch sehr schnell, ich habe einen Codeabschnitt ersetzt, den wir mit xCopy ausgeführt haben, um einige Verzeichnisse zu kopieren, und es hat die Geschwindigkeit sehr schön erhöht. (Ich habe die Repository-Version verwendet)
 IlDan06. Feb. 2012, 11:46
Eine Warnung für Android-Nutzer: Dies ist NICHT in den Standard-Android-APIs enthalten
 Peter03. Sept. 2009, 01:05
Öffentliche Veröffentlichung von Apache Commons IO immer noch bei 1.4, grrrrrrr
 rob17. Juni 2013, 23:57
Wenn Sie Java 7 oder neuer verwenden, können Sie Files.copy verwenden, wie von @GlenBest vorgeschlagen:stackoverflow.com/a/16600787/44737
 Simon Nickerson08. Apr. 2011, 12:08
Ab Dezember 2010 ist Apache Commons IO 2.0.1, das über die NIO-Funktionalität verfügt. Antwort aktualisiert.
 Peter20. Sept. 2008, 05:01
Sehr hilfreich - haben Sie einen Einblick, wann eine offizielle Veröffentlichung diese nio Änderungen beinhalten wird?

können Sie die folgende Methode verwenden.

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();
    }
}
 Solomonoff's Secret07. Sept. 2018, 18:55
Dieser Code ist falsch.InputStream.read kann 0 zurückgeben, auch wenn mehr Daten vorhanden sind.InputStream.read Gibt -1 zurück, wenn keine Daten mehr vorhanden sind. Die Schleife sollte also enden, wenn -1 und nicht 0 zurückgegeben wird.
 Rup18. Mai 2015, 10:59
@EJP Mit "richtig" meine ich 1) die Verwendung der besten verfügbaren APIs, z. die neueren IO, sofern möglich 2) Präsentieren der Aufrufe an Java auf eine Weise, die es leicht erkennen lässt, dass es sich um eine Dateikopie handelt - z. Kanäle, die ganze Dateien zum Lesen und Schreiben darstellen, wie in den anderen Antworten hier - und es in einen einzelnen OS-Aufruf umwandeln. Ich denke, dass dieser Ansatz so langsam ist, wie es wahrscheinlich ist, insbesondere mit einem kleinen Puffer.
 John Henckel29. Okt. 2013, 21:52
Es funktioniert mit Java 6 ohne zusätzliche Gläser.
 Rup19. Juli 2014, 12:02
@EJP OK, aber es ist nicht sehr schlau. Das Kopieren von Dateien sollte ein Betriebssystem- oder Dateisystemvorgang sein, kein Anwendungsvorgang: Java kann hoffentlich eine Kopie erkennen und in einen Betriebssystemvorgang umwandeln, außer wenn Sie die Datei explizit lesen, während Sie dies verhindern. Wenn Sie nicht glauben, dass Java das kann, würden Sie darauf vertrauen, dass es 1K-Lese- und Schreibvorgänge in größeren Blöcken optimiert? Wenn sich Quelle und Ziel in einem langsamen Netzwerk auf einer Remote-Freigabe befanden, ist dies eindeutig eine unnötige Arbeit. Ja, einige JARs von Drittanbietern sind dumm (Guava!), Aber sie fügen eine Menge solcher Dinge hinzu, die richtig gemacht wurden.
 user20742119. Juli 2014, 11:41
@Rup Es ist wesentlich besser als die anderen Antworten hier, (a)da es funktioniert und (b) weil es nicht auf Software von Drittanbietern angewiesen ist.
 Rup23. Okt. 2013, 16:18
Das wird funktionieren, aber ich denke nicht, dass es besser ist als die anderen Antworten hier?
 user20742117. Mai 2015, 20:01
@Rup Ich bin damit einverstanden, dass es sich um eine Betriebssystemfunktion handeln sollte, aber ich kann Ihren Kommentar nicht anders verstehen. Dem Teil nach dem ersten Doppelpunkt fehlt irgendwo ein Verb; Ich würde weder "vertrauen" noch erwarten, dass Java 1k-Blöcke in etwas Größeres verwandelt, obwohl ich sicherlich viel größere Blöcke selbst verwenden würde. Ich würde niemals eine Anwendung schreiben, die gemeinsam genutzte Dateien verwendet. und mir ist nicht bewusst, dass eine Bibliothek von Drittanbietern etwas „Richtigeres“ (was auch immer Sie damit meinen) als diesen Code tut, außer wahrscheinlich, um einen größeren Puffer zu verwenden.
 James Wierzba16. Apr. 2015, 21:36
Lief wie am Schnürchen. Beste Lösung, die keine Bibliotheken von Drittanbietern erfordert und mit Java 1.6 funktioniert. Vielen Dank.

In Java 7 ist es einfach ...

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

Files.copy(src.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
 Uri Agassi20. Juni 2014, 21:59
Was bringt deine Antwort zu Scott's oder Glen's?
 momomo17. Jan. 2015, 11:06
Dies funktioniert nicht für Verzeichnisse. Verdammt, jeder versteht das falsch. Eher eine API-Kommunikation stört Ihren Fehler. Ich habe es auch falsch verstanden.
 Kevin Sadler21. Jan. 2015, 13:01
@momo die frage war wie man eine datei kopiert.
 Kevin Sadler21. Juni 2014, 10:18
Es ist prägnant, weniger ist mehr. Ihre Antworten sind gut und detailliert, aber ich habe sie beim Durchschauen verpasst. Leider gibt es viele Antworten darauf und viele von ihnen sind lang, veraltet und kompliziert, und die guten Antworten von Scott und Glen gingen dabei verloren (ich werde mich dafür aussprechen). Ich frage mich, ob ich meine Antwort verbessern könnte, indem ich sie durch Ausschalten der Exists () - und der Fehlermeldung auf drei Zeilen reduziere.

Wenn getChannel eine Ausnahme auslöst, kann ein offener Stream verloren gehen.Bei großen Dateien versuchen Sie möglicherweise, mehr auf einmal zu übertragen, als das Betriebssystem verarbeiten kann.Sie ignorieren den Rückgabewert von transferFrom, sodass möglicherweise nur ein Teil der Datei kopiert wird.

Deshalborg.apache.tools.ant.util.ResourceUtils.copyResource ist so kompliziert. Beachten Sie auch, dass transferTo unter JDK 1.4 unter Linux funktioniert, obwohl transferFrom in Ordnung ist (sieheBug ID: 5056395) - Jesse Glick Jan

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. Nov. 2013, 11:48
Nicht alle Dateisysteme unterstützen jedoch Dateien mit Speicherzuordnung, und ich denke, dass dies für kleine Dateien relativ teuer ist.
 user20742119. Juli 2014, 11:44
Funktioniert nicht mit Java-Versionen vor 1.4 und es gibt keine Garantie, dass ein einziger Schreibvorgang ausreicht.

Ihre Antwort auf die Frage