2010-10-23 35 views
16

Qual è il modo più veloce per copiare un gran numero di file in Java. Finora ho usato i flussi di file e nio. I flussi complessivi sembrano essere più veloci di nio. Quali esperienze hai fatto fino ad ora?Il modo più veloce per copiare file in Java

+2

Stai facendo una specie di trasformazione sui file mentre li copi? Perché non usare solo le funzioni del filesystem del sistema operativo? –

+0

No, non sto facendo nessuna trasformazione. Ma la gestione degli errori sarebbe molto più difficile quando si copiano più di 10.000 file e l'overhead di generare un thread di sistema quando si copiano file piccoli è troppo grande. – Mato

+0

Ti consiglio di modificare la tua domanda per includere i vincoli che abbiamo scoperto. –

risposta

19

http://www.baptiste-wicht.com/2010/08/file-copy-in-java-benchmark/ potrebbe ottenere la vostra risposta.

Per il benchmark, ho eseguito i test utilizzando file diversi.

  1. piccolo file (5 KB)
  2. file di Media (50 KB)
  3. Big di file (5 MB)
  4. di file FAT (50 MB)
  5. e un file grande (1,3 GB) solo binario

E ho eseguito i test prima utilizzando file di testo e quindi utilizzando file binari. Ho effettuato i test utilizzando tre modalità:

  1. Sullo stesso disco rigido. È un disco rigido IDE da 250 GB con 8 MB di cache. È formattato in Ext4.
  2. Tra due dischi. Ho usato il primo disco e un altro disco rigido SATA da 250 GB con 16 MB di cache. È formattato in Ext4.
  3. Tra due dischi. Ho usato il primo disco e un altro disco rigido SATA da 1 TB con 32 MB di cache. È formattato usando NTFS.

Ho utilizzato un quadro di riferimento, described here, per effettuare i test di tutti i metodi. I test sono stati fatti sul mio personal computer (Ubuntu 10.04 64 bit, Intel Core 2 Duo 3.16 GHz, 6 Go DDR2, SATA Hard Disks). La versione Java utilizzato è un Java 7 a 64 bit Virtual Machine ...

+1

grazie, questo risponde alla mia domanda – Mato

1

Avere java fork da uno script batch del sistema operativo che copia i file. Il tuo codice potrebbe dover scrivere lo script batch.

+1

Già pensato a questo, ma la gestione degli errori sarebbe difficile quando si copiano più di 10.000 file e l'overhead di generare un thread di sistema quando si copiano piccoli file è troppo grande. Inoltre l'app non sarebbe indipendente dalla piattaforma. – Mato

+0

1. Dovrai gestire comunque il controllo degli errori. 2. Hai ragione nel dire che non sarebbe indipendente dalla piattaforma, quindi hai intenzione di eseguirlo su server di diverso tipo? 3. È possibile creare i 10.000 file nella posizione "corretta" per iniziare e non è necessaria una copia? 4. Non generare un thread per file. Un thread per 100 file o qualcosa del genere. –

+0

Sono d'accordo con questo. La copia stupida di file non è un caso d'uso ideale di Java. Se si desidera eseguirlo da Java, inoltrare una chiamata a livello di sistema operativo. – bwawok

9

userei:

import java.io.*; 
import java.nio.channels.*; 

public class FileUtils{ 
    public static void copyFile(File in, File out) 
     throws IOException 
    { 
     FileChannel inChannel = new 
      FileInputStream(in).getChannel(); 
     FileChannel outChannel = new 
      FileOutputStream(out).getChannel(); 
     try { 
      inChannel.transferTo(0, inChannel.size(), 
        outChannel); 
     } 
     catch (IOException e) { 
      throw e; 
     } 
     finally { 
      if (inChannel != null) inChannel.close(); 
      if (outChannel != null) outChannel.close(); 
     } 
    } 

    public static void main(String args[]) throws IOException{ 
     FileUtils.copyFile(new File(args[0]),new File(args[1])); 
    } 
} 

Se uno dei tuoi file sono più grandi di 64M in Windows potrebbe essere necessario guardare a questo: http://forums.sun.com/thread.jspa?threadID=439695&messageID=2917510

+7

catch (IOException e) { throw e; } <--- nice one – unbeli

+0

È solo un codice di esempio. –

+1

Grazie questo è stato enormemente più veloce di quello che stavo usando! –

1

È possibile utilizzare uno implementazione fileutils di Apache Commons-IO libreria per copiare il file

FileUtils.copyFile(new File(sourcePath), new File(destPath)); 

che utilizza FileChannel per IO operazione.

Oppure utilizzare il metodo java.nio.file.Filescopy().

Problemi correlati