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

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

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

【问题讨论】:

标签: c++ linux g++ filesystems


【解决方案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 librarystd::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 上,所以这超出了这个特定问题的范围)。您可以通过内存映射文件进行复制(这会更快,顺便说一句)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多