【问题标题】:Why do we need to write an own copy program while we can use copy shell command?为什么我们需要编写自己的复制程序而我们可以使用复制shell命令?
【发布时间】:2015-11-13 12:08:23
【问题描述】:

我想在我的 C/C++ 程序中复制大文件(~ 10 GB),手头有两个选项:1)编写我自己的复制函数(可能使用大缓冲区),以及 2)调用系统复制命令(在 Windows 上复制,在 Linux 上复制)。

正如我所见,在 Windows 上使用“Ctrl + C”和“Ctrl + V”时,复制大文件的速度非常快。我不确定我们是否能比 Windows 操作系统做得更好。

哪个是最好的选择?

【问题讨论】:

  • 在 Windows 中,为什么不使用旨在更有效地处理大文件和文件集的命令之一呢?像xcopyrobocopy 至少还有一个,我忘记名字了。
  • 我想说最好的选择是使用boost::filesystem::copy,同时我们等待实现与std::experimental::filesystem::copy一起发布。
  • 我认为这是 Stack Overflow 问答提供了一些不同的方式来进行这样的复制(以及一些相对时间)stackoverflow.com/questions/10195343/…
  • @MichaelPetch:我在发布我的问题之前确实阅读了这个问题。我想知道为什么我们不使用复制 shell 命令而不是编写一个新命令?例如,在 Windows 上,robocopy 需要约 1.5 分钟来复制 5 GB(约 55 MB/秒)的文件(Windows 7,核心 i5,8 GB)。我认为这已经非常快了。我们可以自己制造一个更快的吗?
  • 便携性是其中之一。如果您编写 C++(或 C 代码)来进行复制,那么您在什么操作系统上使用它并不重要 - 它应该在所有操作系统上以相同的方式运行使用您的方法,您需要了解底层复制机制,就像您提到的 @987654326 @、cp

标签: c++ file-io stream


【解决方案1】:

如果是我,我会避免进行系统调用并做类似的事情:

    int main()
    {
         std::ifstream  src("from.ogv", std::ios::binary);
         std::ofstream  dst("to.ogv",   std::ios::binary);
         dst << src.rdbuf();
    }

【讨论】:

  • 是否有任何“关键”原因可以避免系统调用?我做了一个程序,它读取大小为 8192 的缓冲区,然后写入输出文件,但与 Windows 中的“Ctrl + C”和“Ctrl + V”相比,它要慢得多。
  • 这不是在避免“系统调用”,而是在避免不同的system 调用。这也缺乏理由,这是这个问题的重点。
【解决方案2】:

通过适当的实施,滚动您自己的代码™ 为您提供了对 shell 副本的灵活性。例如,更容易中止操作,并向用户提供进度。

顺便说一句,当您看到 Windows 快速复制文件时 - 这只是透视图。文件资源管理器将副本排队或以其他方式在后台进行。它需要大约相同的时间,例如CopyFileExsendfile 直到复制完成并且文件可用。

【讨论】:

    【解决方案3】:

    不使用 shell 来使用语言中的基本任务的原因根本与性能无关——更多的是关于安全性和可移植性。您不会在您的语言中使用 eval ,也不会尝试连接字符串来创建 SQL 查询 - 但是您可以通过连接字符串来创建 shell 命令。

    Brett Hale 的“解决方案”很方便地没有提及所有这些,而是​​在“自己动手”注释后面隐藏了确保安全和可移植所需的代码 - 事实上,当您这样做时,您最终会得到更多代码比手卷复制功能,它仍然会是错误的。如果那里有错误,用户可以注入命令(例如,使用目标文件a_file" || rm -rf --no-preserve-root 运行它)。此外,您还依赖于 shell,它本身可能有错误(请参阅 Shellshock)

    Calvin 的回答正确地提到了为什么 shell 完成的复制操作可能工作得更快——它可以做更多的技巧来让它看起来复制得更快。事实上,shell 复制操作并没有内在的魔力。 “性能问题”不是问题,因为主要瓶颈是实际读写。

    此外,您提出了错误的二分法,因为您没有考虑使用第三种选择:第三方库。其中之一是Boost.Filesystem,它具有复制功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2021-10-25
      • 2012-10-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多