【发布时间】:2010-09-09 21:30:40
【问题描述】:
编写文件复制例程会更快/更高效,还是我应该只执行对 cp 的系统调用?
(文件系统可能不同 [nfs、local、reiser 等],但它总是在 CentOS linux 系统上)
【问题讨论】:
标签: c++ linux g++ filesystems
编写文件复制例程会更快/更高效,还是我应该只执行对 cp 的系统调用?
(文件系统可能不同 [nfs、local、reiser 等],但它总是在 CentOS linux 系统上)
【问题讨论】:
标签: c++ linux g++ filesystems
Invoking shell 使用 system () 函数效率不高,也不是很安全。
在 Linux 中复制文件最有效的方法是使用 sendfile () 系统调用。 在 Windows 上,应使用 CopyFile () API 函数或其相关变体之一。
#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;
}
如果您不希望您的代码依赖于平台,您可以坚持使用更便携的解决方案 - Boost File System library 或 std::fstream。
使用 Boost (more complete example) 的示例:
copy_file (source_path, destination_path, copy_option::overwrite_if_exists);
使用 C++ 的示例std::fstream:
ifstream f1 ("input.txt", fstream::binary);
ofstream f2 ("output.txt", fstream::trunc|fstream::binary);
f2 << f1.rdbuf ();
【讨论】:
编写文件复制例程不会节省时间。
调用系统来shell cp是资源密集型的。
弄清楚您可以用来复制文件的系统(函数)调用会为您提供更好的服务。例如。如果我没记错的话,在 Windows 上它只是 CopyFile(src, dst)。
【讨论】:
system("cp a.txt b.txt"); 的执行路径与 Windows 上的 CopyFile("a.txt", "b.txt"); 有很大不同。我怀疑其他平台上也有类似的情况。
使用自己的例程可以控制用于复制的块的大小,而 cp 无法做到这一点。此外,您可以生成不同的线程来读取和写入数据(以进一步加快进程)。最后,生成外部进程需要额外的时间(如果您复制小文件,这一点很重要)。
【讨论】:
C++ File IO 更便携,更底层,因此更灵活。
【讨论】:
我认为操作系统知道将文件 A 复制到文件 B 的最有效方法。这同样适用于任何 api 函数。
【讨论】: