views:

95

answers:

5

Would it be quicker/efficient to write a file copy routine or should I just execute a System call to cp?

(The file system could differ [nfs, local, reiser, etc], however it would always be on a CentOS linux system)

A: 

With your own routine you can control the size of the block used for copying, which you can't do with cp. Also, you can spawn different threads for reading and writing data (to further speed up process). Finally, spawning an external process takes extra time (important if you copy small files).

Eugene Mayevski 'EldoS Corp
+2  A: 

It would not be time efficient to write a file copy routine.

It is resource intensive to call system to shell a cp.

You'll be far better served by figuring out the system (function) call that you can make to copy the file. E.g. on Windows it's just CopyFile(src, dst) if I recall correctly.

dash-tom-bang
That appears to be what the OP was thinking of doing, by executing a system call.
David Thornley
No, calling the system() function is not the same as making a system call.
DeadMG
The execution path for `system("cp a.txt b.txt");` is substantially different from `CopyFile("a.txt", "b.txt");` on Windows. I suspect that something similar is the case on other platforms as well.
dash-tom-bang
A: 

C++ File IO is more portable and more low-level, so it is more flexible.

PC2st
A: 

I would put my money on that the OS knows the most efficient way to copy file A to file B. The same applies for any api functions.

Alexander Rafferty
You'd lose - the OS is optimized for "average" task, and for almost any specialized task there's room for optimization.
Eugene Mayevski 'EldoS Corp
In any situation, you are copying bytes from one location to another. How could this be specialized or optimized?
Alexander Rafferty
Simply: you can effectively parallelize reading and writing, if you know the amounts of data and source and target devices. You can adjust size of the data block to be really huge. You can use asynchronous reading and writing (on Windows, at least, so this is out of scope of this particular question). You can copy via memory-mapped file (this will be faster, btw).
Eugene Mayevski 'EldoS Corp
+3  A: 

Invoking a shell by using system () function is not efficient and not very secure.

The most efficient way to copy a file in Linux is to use sendfile () system call. On Windows, CopyFile () API function or one of its related variants should be used.

Example using 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;
}

If you do not want your code to be platform dependent, you may stick with more portable solutions - Boost File System library or std::fstream.

Example using Boost (more complete example):

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

Example using C++ std::fstream:

ifstream f1 ("input.txt", fstream::binary);
ofstream f2 ("output.txt", fstream::trunc|fstream::binary);
f2 << f1.rdbuf ();
Vlad Lazarenko
In most cases, copying files should be left up to the OS. The OS should be more efficient since file copying is one of its objectives in life.
Thomas Matthews
@Thomas, you are right. I've updated my answer accordingly. Thank you.
Vlad Lazarenko