ZipStream在PHP中动态创建的zip文件无法在OSX中打开

Zor*_*ena 10 php macos zip

我有一个包含大量媒体文件的PHP站点,用户需要能够一次下载多个文件作为.zip.我正在尝试使用ZipStream通过"存储"压缩动态地为拉链提供服务,所以我实际上不必在服务器上创建一个zip,因为有些文件非常庞大而且压缩它们的速度非常慢.

这很好用,我可以尝试的每个zip程序打开生成的文件,除了OS X的默认解压缩程序Archive Utility之外没有任何错误.双击.zip文件,Archive Utility确定它看起来不是真正的zip,而是压缩成.cpgz文件.

在OS X终端或StuffIt Expander中使用解压缩或同步解压缩文件没有问题,但我需要默认程序(Archive Utility)才能为我们的用户工作.

在其他可接受的zip文件中,什么样的东西(标志等)可以使Archive Utility认为文件不是有效的zip?

我已经阅读了这个问题,这似乎描述了一个类似的问题,但我没有任何通用的位域位设置,所以它不是第三位问题,我很确定我有有效的crc-32,因为当我不要,WinRAR会发挥合适.

我很乐意发布一些代码或链接到"坏"zip文件,如果它会有所帮助,但我只是使用ZipStream,强制它进入"大文件模式"并使用"store"作为压缩方法.

编辑 - 我也尝试了"deflate"压缩算法并得到相同的结果,所以我不认为它是"商店".值得指出的是,我一次从存储服务器中下载文件并在它们到达时将它们发送出来,因此需要在发送任何内容之前下载所有文件的解决方案不可行(极端例如5GB +的20MB文件.用户不能等到所有5GB都在下载开始之前转移到压缩服务器,否则他们会认为它已经坏了

这是一个140字节的"存储"压缩测试zip文件,它表现出这种行为:http://teknocowboys.com/test.zip

Zor*_*ena 9

问题出现在"需要提取的版本"字段中,我通过对ZipStream创建的文件和Info-zip创建的文件进行十六进制差异并查看差异,尝试解决它们.

ZipStream默认将其设置为0x0603.Info-zip将其设置为0x000A.具有以前值的Zip文件似乎在Archive Utility中不会打开.也许它不支持该版本的功能?

将"需要提取的版本"强制为0x000A会使生成的文件在Archive Utility中打开,就像在其他任何地方一样.

编辑:此问题的另一个原因是如果使用Safari(用户代理版本> = 537)下载了zip文件,并且在发送Content-Length标头时您报告的文件大小不足.

我们采用的解决方案是检测Safari> = 537服务器端,如果你正在使用它,我们确定内容长度大小和实际大小之间的差异(你如何做到这取决于你的具体应用)和调用之后$ zipStream-> finish(),我们回显chr(0)以达到正确的长度.生成的文件在技术上不正确,并且您在zip中放置的任何注释都不会显示,但所有zip程序都可以打开它并解压缩文件.

如果你误报了Content-Length,IE需要相同的黑客,但不是下载一个不起作用的文件,它只是不会完成下载并抛出"下载中断".

  • 救生员。我遇到了完全相同的问题(甚至使用 ZipStream)。 (2认同)

Mer*_*lin 5

使用 ob_clean(); 冲洗();

例子 :

    $file =  __UPLOAD_PATH . $projectname . '/' . $fileName;

    $zipname = "watherver.zip"
    $zip = new ZipArchive(); 
    $zip_full_path_name = __UPLOAD_PATH . $projectname . '/' . $zipname;
    $zip->open($zip_full_path_name, ZIPARCHIVE::CREATE);
    $zip->addFile($file); // Adding one file for testing
    $zip->close();

    if(file_exists($zip_full_path_name)){
        header('Content-type: application/zip');
        header('Content-Disposition: attachment; filename="'.$zipname.'"');
        ob_clean();
        flush();
        readfile($zip_full_path_name);
        unlink($zip_full_path_name);
    }
Run Code Online (Sandbox Code Playgroud)