我正在尝试用PHP编写一个下载大型zip文件(2,663,439,370字节)的脚本,我遇到了一个有趣但令人沮丧的问题:脚本下载了第一个2.147.483.647字节,然后继续下载文件,而是附加字节编号为2.147.483.648,2.147.483.649等等,它继续从字节编号1开始向文件追加字节。
因此,下载的文件来自:字节1,字节2,...字节2.147.483.647,字节1,字节2 ......等等。
我注意到2.147.483.647是32字节系统可以存储的最大整数值。但是,我的服务器是一个64字节的系统,可以存储大于该值的值。为了证明这一点,var_dump((int)2147483648)返回正确的整数。
我的下载脚本尽可能正确(通过复制粘贴从php.net获取)
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="Certificat.zip"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
有没有人遇到过这个问题?
答案 0 :(得分:1)
阅读5.6源代码,<my-item *ngFor="let item of items" [item]="item"></my-item>
返回readfile
。 Here's the source reference
再挖掘一下,出现这个宏处理long int定义,通常是 4个字节,给我们带符号的最大值整数,你的函数停在。我没有深入挖掘这个,这是我的假设,考虑到你所经历的行为,这对我来说已经足够了(但不适合那些更迂腐的人)。
另一方面,我个人从未使用RETURN_LONG(size)
,readfile
/ fopen
组合在性能和使用的内存方面总是被证明更好。既然你可以阅读块,而不是吞噬2GB的猛犸象,那么它在服务器资源上就更容易了。
答案 1 :(得分:0)
我不确定它对你的情况是否有帮助,但你应该删除
header('Content-Length: ' . filesize($zipname));
当我从正在进行的流加载时,我做了几次,浏览器继续加载,直到脚本停止响应内容。我不确定它是否适用于这个大文件,它可能是php限制。
答案 2 :(得分:0)
我最后通过删除readfile()
函数并使用fopen()
和fread()
自行输出文件内容来解决问题。
然而readfile()
&#39;处理这些大文件时失败仍然是一个开放的主题(我已经阅读了php.net上的文档,我无法找到关于此类问题的任何注释)。所以我还在等那位经验丰富的程序员开导我:)。