【问题标题】:Copy large files (over 2 GB) in PHP在 PHP 中复制大文件(超过 2 GB)
【发布时间】:2011-09-27 17:21:27
【问题描述】:

我需要通过 PHP 复制一些大文件 (6 GB)。我怎样才能做到这一点? Copy() 函数做不到。

我在 Windows 32/64 上使用 PHP 5.3。

【问题讨论】:

  • 为什么copy 不能这样做?您收到错误消息吗?
  • 复制到哪里?目标文件系统能否支持 6GB 文件?
  • 我认为 PHP 有一些限制 (> 2 GB) php.net/manual/en/function.copy.php#69001 copy() 从文件中获取只有几 MB,没有错误。 filesize() 也有问题...是的,目标文件系统是 NTFS
  • @Gordon 因为 copy() 似乎在每 4 GiB 后将内部偏移位置恢复为 0,即使在 64 位系统上的 64 位 PHP 版本上也是如此。
  • @StanE 似乎与文件系统相关。见bugs.php.net/bug.php?id=81145

标签: php file copy


【解决方案1】:

应该这样做。

function chunked_copy($from, $to) {
    # 1 meg at a time, you can adjust this.
    $buffer_size = 1048576; 
    $ret = 0;
    $fin = fopen($from, "rb");
    $fout = fopen($to, "w");
    while(!feof($fin)) {
        $ret += fwrite($fout, fread($fin, $buffer_size));
    }
    fclose($fin);
    fclose($fout);
    return $ret; # return number of bytes written
}

【讨论】:

    【解决方案2】:

    最近版本的 PHP 复制带有块的文件,所以今天你可以安全地使用 php copy() 函数

    【讨论】:

    • 这里的“最近”是什么意思。如果有版本号,这个答案会好很多...
    • 不,我不认为这是正确的。我正在使用编译为 64 位的 PHP 8.0.7(因此它在内部使用 8 字节整数)。 copy() 仍然不支持复制大于 4 GiB 的文件。它确实会复制它们,但它会在 4 GiB 之后从偏移量 0 开始写入。
    【解决方案3】:

    如果copy不起作用,你可以试试

    示例

    stream_copy_to_stream(
        fopen('/path/to/input/file.txt', 'r'),
        fopen('/path/to/output/file.txt', 'w+')
    );
    

    另见https://bugs.php.net/bug.php?id=81145

    【讨论】:

    • 你应该在之后关闭这些,除非你的脚本执行之后立即停止。
    • 我在 64 位 Windows 10 版本和 PHP 8.0.7 的 64 位版本上进行了尝试。 stream_copy_to_stream() 似乎对超过 4 GiB 的文件有同样的问题。在 4 GiB 之后,文件内容会重复。
    【解决方案4】:

    如果是 linux 机器,你可以使用exec()

    $srcFile = escapeshellarg($pathToSrcFile);
    $trgFile = escapeshellarg($pathToTrgFile);
    
    exec("cp $srcFile $trgFile");
    

    【讨论】:

    • .. windows,但如果可能的话,我更喜欢 PHP 方式。
    • @Adrian 是的,但是你需要使用'copy'命令,而不是'cp'。
    • 是的,我认为这是可以理解的
    • 老实说,从所有答案中,这是唯一一个理智的。
    • 因为我的应用程序被设计为 Nette PHP 框架的一个组件 - 它是一个简单的文件管理器,我想要在服务器上禁用 exec 使用时的解决方法。分块副本是我认为的最佳解决方案。
    【解决方案5】:

    我会逐个 X 字节地复制它(每次迭代若干兆)。
    X 将是最优化的大小,具体取决于您的机器。
    而且我不会通过 Web 服务器执行此操作,而是作为一个独立的脚本,通过 cron 或一次调用它 (cli) 运行。

    【讨论】:

      【解决方案6】:

      如果您想将文件从一台服务器复制到另一台服务器,并且您在这两台服务器上都具有 ftp 访问权限,那么您只需在源系统上使用 ftp 'put' 命令即可轻松地将大文件发送到其他系统。

      【讨论】:

        猜你喜欢
        • 2014-12-16
        • 1970-01-01
        • 2011-06-30
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 2012-03-09
        • 2013-02-18
        • 2013-08-15
        相关资源
        最近更新 更多