2010-09-09 13 views
11

sarebbe più veloce/efficiente di scrivere una copia del file di routine o devo solo eseguire una chiamata di sistema per cp?C++ FileIO Copy -confrontarli- sistema ("cp file1.x file2.x)

(Il file il sistema potrebbe differire [nfs, local, reiser, ecc], tuttavia sarebbe sempre su un sistema linux CentOS)

+0

possibile duplicato di [copiare un file in un modo sano, sicuro ed efficiente] (http: // stackoverflow.com/questions/10195343/copy-a-file-in-an-sane-safe-and-efficient-way) –

risposta

20

Invoking un shell utilizzando la funzione system() non è efficiente e non molto sicuro.

Il modo più efficace per copiare un file in Linux è quello di utilizzare sendfile() chiamata di sistema. Su Windows, CopyFile() È necessario utilizzare la funzione API o una delle sue varianti correlate.

Example utilizzando sendfile:

#include <fcntl.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <sys/sendfile.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main (int argc, char* argv[]) 
{ 
int read_fd; 
int write_fd; 
struct stat stat_buf; 
off_t offset = 0; 

/* Open the input file. */ 
read_fd = open (argv[1], O_RDONLY); 
/* Stat the input file to obtain its size. */ 
fstat (read_fd, &stat_buf); 
/* Open the output file for writing, with the same permissions as the 
    source file. */ 
write_fd = open (argv[2], O_WRONLY | O_CREAT, stat_buf.st_mode); 
/* Blast the bytes from one file to the other. */ 
sendfile (write_fd, read_fd, &offset, stat_buf.st_size); 
/* Close up. */ 
close (read_fd); 
close (write_fd); 

return 0; 
} 

Se non si desidera che il codice sia dipendente dalla piattaforma, si può attaccare con più soluzioni portatili - Boost File System library o std::fstream.

Esempio con Boost (more complete example):

copy_file (source_path, destination_path, copy_option::overwrite_if_exists); 

Esempio in C++ std::fstream:

ifstream f1 ("input.txt", fstream::binary); 
ofstream f2 ("output.txt", fstream::trunc|fstream::binary); 
f2 << f1.rdbuf(); 
+1

Nella maggior parte dei casi, la copia dei file deve essere lasciata al sistema operativo. Il sistema operativo dovrebbe essere più efficiente poiché la copia dei file è uno dei suoi obiettivi nella vita. –

+0

@Thomas, hai ragione. Ho aggiornato la mia risposta di conseguenza. Grazie. –

0

Con la tua routine puoi controllare la dimensione del blocco utilizzato per la copia, che non puoi fare con cp. Puoi anche generare thread diversi per leggere e scrivere dati (per accelerare ulteriormente il processo) Infine, generare un processo esterno richiede più tempo (importante se copi piccoli file)

1

Non sarebbe tempo efficiente scrivere una routine di copia di file.

È molto impegnativo chiamare il sistema per eseguire il shell di un cp.

Sarà molto meglio trovare la chiamata di sistema (funzione) che è possibile effettuare per copiare il file. Per esempio. su Windows è solo CopyFile(src, dst) se ricordo correttamente.

+0

Questo sembra essere ciò che l'OP stava pensando di fare, eseguendo una chiamata di sistema. –

+6

No, chiamare la funzione system() non equivale a effettuare una chiamata di sistema. – Puppy

+2

Il percorso di esecuzione per 'system (" cp a.txt b.txt ");' è sostanzialmente diverso da 'CopyFile (" a.txt "," b.txt ");' su Windows. Sospetto che qualcosa di simile sia il caso anche su altre piattaforme. –

0

File C++ L'IO è più portatile e di livello più basso, quindi è più flessibile.

0

Vorrei mettere i miei soldi sul fatto che il sistema operativo conosce il modo più efficiente per copiare il file A nel file B. Lo stesso vale per qualsiasi funzione API.

+0

Si perderebbe: il sistema operativo è ottimizzato per l'attività "media" e per quasi tutte le attività specializzate c'è spazio per l'ottimizzazione. –

+0

In qualsiasi situazione, si copiano byte da una posizione a un'altra. Come potrebbe essere specializzato o ottimizzato? –

+0

Semplicemente: è possibile parallelizzare in modo efficace la lettura e la scrittura, se si conoscono le quantità di dati e dispositivi di origine e di destinazione. È possibile regolare la dimensione del blocco dati per essere davvero enorme. È possibile utilizzare la lettura e la scrittura asincrona (almeno su Windows, quindi non rientra nell'ambito di questa particolare domanda). È possibile copiare tramite file mappati in memoria (questo sarà più veloce, btw). –