C++ FileIO Copy -VS- System("cp file1.x file2.x)

Posted

技术标签:

【中文标题】C++ FileIO Copy -VS- System("cp file1.x file2.x)【英文标题】: 【发布时间】:2010-09-09 21:30:40 【问题描述】:

编写文件复制例程会更快/更高效,还是我应该只执行对 cp 的系统调用?

(文件系统可能不同 [nfs、local、reiser 等],但它总是在 CentOS linux 系统上)

【问题讨论】:

Copy a file in an sane, safe and efficient way的可能重复 【参考方案1】:

Invoking shell 使用 system () 函数效率不高,也不是很安全。

在 Linux 中复制文件最有效的方法是使用 sendfile () 系统调用。 在 Windows 上,应使用 CopyFile () API 函数或其相关变体之一。

Example 使用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;

如果您不希望您的代码依赖于平台,您可以坚持使用更便携的解决方案 - 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 ();

【讨论】:

在大多数情况下,复制文件应该留给操作系统。操作系统应该更高效,因为文件复制是其生活目标之一。 @Thomas,你是对的。我已经相应地更新了我的答案。谢谢。【参考方案2】:

编写文件复制例程不会节省时间。

调用系统来shell cp是资源密集型的。

弄清楚您可以用来复制文件的系统(函数)调用会为您提供更好的服务。例如。如果我没记错的话,在 Windows 上它只是 CopyFile(src, dst)

【讨论】:

这似乎是 OP 正在考虑做的事情,通过执行系统调用。 不,调用 system() 函数与进行系统调用不同。 system("cp a.txt b.txt"); 的执行路径与 Windows 上的 CopyFile("a.txt", "b.txt"); 有很大不同。我怀疑其他平台上也有类似的情况。【参考方案3】:

使用自己的例程可以控制用于复制的块的大小,而 cp 无法做到这一点。此外,您可以生成不同的线程来读取和写入数据(以进一步加快进程)。最后,生成外部进程需要额外的时间(如果您复制小文件,这一点很重要)。

【讨论】:

【参考方案4】:

C++ File IO 更便携,更底层,因此更灵活。

【讨论】:

【参考方案5】:

我认为操作系统知道将文件 A 复制到文件 B 的最有效方法。这同样适用于任何 api 函数。

【讨论】:

你输了 - 操作系统针对“普通”任务进行了优化,几乎所有专业任务都有优化空间。 在任何情况下,您都在将字节从一个位置复制到另一个位置。这怎么能被专门化或优化? 简单地说:如果您知道数据量以及源和目标设备,您可以有效地并行读取和写入。您可以将数据块的大小调整为非常大。您可以使用异步读写(至少在 Windows 上,所以这超出了这个特定问题的范围)。您可以通过内存映射文件进行复制(这会更快,顺便说一句)。

以上是关于C++ FileIO Copy -VS- System("cp file1.x file2.x)的主要内容,如果未能解决你的问题,请参考以下文章

FileIO工具类

python 读写文件 FileIO

C ++ BOOST对`boost :: filesystem :: detail :: copy_file的未定义引用

C++ 文件 IO:读取和写入 16 位字

C++、std::copy 和模板

在结构数组上使用 c++ std::copy