2008-11-18 5 views

Antwort

71

Hier ist, wie dies mit java.nio Operationen zu tun:

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

     // previous code: destination.transferFrom(source, 0, source.size()); 
     // to avoid infinite loops, should be: 
     long count = 0; 
     long size = source.size();    
     while((count += destination.transferFrom(source, count, size-count))<size); 
    } 
    finally { 
     if(source != null) { 
      source.close(); 
     } 
     if(destination != null) { 
      destination.close(); 
     } 
    } 
} 
+5

Wenn die Datei existiert, wird der Inhalt angehängt oder überschrieben? – Janusz

+0

@Rigo Dies verschiebt nur Dateien, ich bin nicht in der Lage, Verzeichnisse zu verschieben – Arasu

+11

Es ist erwähnenswert, dass Java 7 hat einfachere [Kopieren/Verschieben Methoden] (http://docs.oracle.com/javase/tutorial/essential/io/ Kopie.html). – Tharwen

40

Noch nicht, aber die New NIO (JSR 203) wird Unterstützung für diese gemeinsamen Operationen haben.

In der Zwischenzeit gibt es ein paar Dinge zu beachten.

File.renameTo funktioniert im Allgemeinen nur auf dem gleichen Dateisystemvolume. Ich denke dies als das Äquivalent zu einem "mv" -Befehl. Verwenden Sie es, wenn Sie können, aber für die allgemeine Unterstützung von Kopieren und Verschieben müssen Sie einen Fallback haben.

Wenn ein Umbenennen nicht funktioniert, müssen Sie die Datei tatsächlich kopieren (Löschen des Originals mit File.delete, wenn es sich um eine "Verschieben" -Operation handelt). Verwenden Sie dazu die Methoden FileChannel.transferTo oder FileChannel.transferFrom. Die Implementierung ist plattformspezifisch, aber im Allgemeinen vermeiden Implementierungen beim Kopieren von einer Datei in eine andere den Transport von Daten zwischen Kernel und Benutzerraum, was zu einem großen Effizienzgewinn führt.

17

Check out: http://commons.apache.org/io/

Es hat zu kopieren, und wie das JDK bereits erklärt hat zu bewegen.

Implementieren Sie keine eigene Kopiermethode. Es gibt so viele Floating da draußen ...

+0

Commons IO hat Einschränkungen in Bezug auf die Größe der Dateien, die es kopieren kann. Für eine allgemeine Lösung wäre eine robustere Implementierung zu erwarten. – erickson

+3

Die Implementierung der eigenen Kopiermethode ist trivial und bedeutet, dass Sie nicht auf eine ganze Bibliothek angewiesen sind. * Implementieren Sie Ihre eigene –

+17

Copy-Methode ist bei weitem nicht trivial. Sie können problemlos einen korrekten Eintrag erstellen, der keine Streams verwendet, und einen schnellen, aber inkorrekten, der NIO verwendet. Implementieren Sie nie eigene Dienstprogramme, wenn es Qualitätsbibliotheken gibt. – Pyrolistical

10

Vorherige Antworten scheinen veraltet sein.

Javas File.renameTo() ist wahrscheinlich die einfachste Lösung für API 7 und scheint gut zu funktionieren. Seien Sie vorsichtig ES WIRFT KEINE AUSNAHMEN, sondern gibt wahr/falsch zurück !!!

Beachten Sie, dass in früheren Versionen Probleme aufgetreten sind (wie NIO).

Wenn Sie eine frühere Version verwenden müssen, überprüfen Sie here.

Here's an example for API7: 
     File f1= new File("C:\\Users\\.....\\foo"); 
     File f2= new File("C:\\Users\\......\\foo.old"); 
     System.err.println("Result of move:"+f1.renameTo(f2)); 

Alternativ:

System.err.println("Move:" +f1.toURI() +"--->>>>"+f2.toURI()); 
    Path b1=Files.move(f1.toPath(), f2.toPath(), StandardCopyOption.ATOMIC_MOVE ,StandardCopyOption.REPLACE_EXISTING);); 
    System.err.println("Move: RETURNS:"+b1); 
+3

Wenn Sie erhalten "Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird." Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird Datei vor dem Verschieben ..... – ntg

+2

Es gibt andere unerwartete Situationen, in denen es fehlschlägt, zB unter Linux Wenn Sie zwei verschiedene Dateisysteme unter/mnt/a/mnt/b haben, können Sie eine Datei nicht umbenennen/mnt/a/file1 to/mnt/b/file2, da es sich um eine Verschiebeoperation handelt, würde File.renameTo in diesem Fall fehlschlagen – xask

+1

Dies ist die beste Lösung.Verwenden Sie nur Files.move(), wenn Sie besorgt sind, dass der Umbenennungsvorgang fehlschlägt. – xtian

7

Try org.apache.commons.io.FileUtils (General Dateimanipulation Dienstprogramme) zu verwenden. Einrichtungen sind in den folgenden Methoden zur Verfügung gestellt:

(1) FileUtils.moveDirectory(File srcDir, File destDir) => Verschieben ein Verzeichnis.

(2) FileUtils.moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) => Verschiebt ein Verzeichnis in ein anderes Verzeichnis.

(3) FileUtils.moveFile(File srcFile, File destFile) => Verschiebt eine Datei.

(4) FileUtils.moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) => Verschiebt eine Datei in ein Verzeichnis.

(5) FileUtils.moveToDirectory(File src, File destDir, boolean createDestDir) => Verschiebt eine Datei oder ein Verzeichnis zum Zielverzeichnis .

Es ist einfach, einfach und schnell.

+0

Sind diese Funktionen atomar? – Sumit

0

Interessante Beobachtung: Versucht, die gleiche Datei über verschiedene Java-Klassen und gedruckte Zeit in Nano-Sekunden zu kopieren.

Dauer unter Verwendung von Outputstream Bytestrom: 4 965 078

Dauer unter Verwendung BufferedOutputStream: 1 237 206

Dauer unter Verwendung von (Zeichentextleser: 2 858 875

Dauer BufferedReader Verwendung (gepufferte Zeichentextstrom : 1 998 005

Dauer verwenden (Files NIO kopieren): 18 351 115

w henne mit Files Nio Kopieroption dauerte fast 18 mal länger !!! Nio ist die langsamste Option zum Kopieren von Dateien und BufferedOutputStream sieht wie die schnellste aus. Ich habe für jede Klasse dieselbe einfache Textdatei verwendet.