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)的主要内容,如果未能解决你的问题,请参考以下文章
C ++ BOOST对`boost :: filesystem :: detail :: copy_file的未定义引用