由ZipStream在PHP中动态创建的zip文件无法在OSX中打开 [英] Dynamically created zip files by ZipStream in PHP won't open in OSX

查看:273
本文介绍了由ZipStream在PHP中动态创建的zip文件无法在OSX中打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个PHP网站,其中包含许多媒体文件,并且用户需要能够一次以.zip格式下载多个文件.我正在尝试使用 ZipStream 通过存储"压缩即时提供zip.因此,我实际上不必在服务器上创建zip,因为其中一些文件很大,而且压缩所有文件的速度都非常慢.

I have a PHP site with a lot of media files and users need to be able to download multiple files at a time as a .zip. I'm trying to use ZipStream to serve the zips on the fly with "store" compression so I don't actually have to create a zip on the server, since some of the files are huge and it's prohibitively slow to compress them all.

这很好用,我尝试过的每个zip程序都可以打开文件,没有错误,除了OS X的默认解压缩程序Archive Utility.双击.zip文件,然后Archive Utility决定它看起来不是真正的zip,而是压缩为.cpgz文件.

This works great and the resulting files can be opened by every zip program I've tried with no errors except for OS X's default unzipping program, Archive Utility. You double click the .zip file and Archive Utility decides it doesn't look a real zip and instead compresses into a .cpgz file.

在OS X终端或StuffIt Expander中使用解压缩或同上,可以毫无问题地解压缩文件,但是为了我们的用户,我需要默认程序(存档实用程序)才能工作.

Using unzip or ditto in the OS X terminal or StuffIt Expander unzips the file with no problem but I need the default program (Archive Utility) to work for the sake of our users.

其他可以接受的zip文件中的哪些内容(标志等)会使存档实用程序"误认为文件不是有效的zip?

What sort of things (flags, etc.) in otherwise acceptable zip files can trip Archive Utility into thinking a file isn't a valid zip?

我已阅读此问题,它似乎描述了类似的问题,但我没有设置任何通用位域位,因此它不是第三位问题,我很确定我拥有有效的crc-32,因为当我不这样做时't,WinRAR很合适.

I've read this question, which seems to describe a similar issue but I don't have any of the general purpose bitfield bits set so it's not the third bit issue and I'm pretty sure I have valid crc-32's because when I don't, WinRAR throws a fit.

我很乐意发布一些代码或指向错误的" zip文件的链接(如果有帮助的话),但我几乎只是使用ZipStream,将其强制为大文件模式",并使用存储"作为压缩方法.

I'm happy to post some code or a link to a "bad" zip file if it would help but I'm pretty much just using ZipStream, forcing it into "large file mode" and using "store" as the compression method.

编辑-我也尝试了放气"压缩算法,并获得了相同的结果,因此我不认为它是商店".还值得指出的是,我一次要从存储服务器中提取文件,并在它们到达时将其发送出去,因此,要求在发送任何内容之前先下载所有文件的解决方案是行不通的(极端例如5GB +的20MB文件.用户不能等到所有5GB传输到zip服务器后才开始下载,否则他们会认为它已损坏)

Edit - I've tried the "deflate" compression algorithm as well and get the same results so I don't think it's the "store". It's also worth pointing out that I'm pulling down the files one a time from a storage server and sending them out as they arrive so a solution that requires all the files to be downloaded before sending anything isn't going to be viable (extreme example is 5GB+ of 20MB files. User can't wait for all 5GB to transfer to zipping server before their download starts or they'll think it's broken)

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

Here's a 140 byte, "store" compressed, test zip file that exhibits this behavior: http://teknocowboys.com/test.zip

推荐答案

问题出在需要提取的版本"字段中,该字段是通过对ZipStream创建的文件与Info创建的文件进行十六进制比较而发现的-zip并仔细研究差异,尝试解决它们.

The problem was in the "version needed to extract" field, which I found by doing a hex diff on a file created by ZipStream vs a file created by Info-zip and going through the differences, trying to resolve them.

ZipStream默认情况下将其设置为0x0603. Info-zip将其设置为0x000A.具有前一个值的Zip文件似乎没有在存档实用程序"中打开.也许它不支持该版本的功能?

ZipStream by default sets it to 0x0603. Info-zip sets it to 0x000A. Zip files with the former value don't seem to open in Archive Utility. Perhaps it doesn't support the features at that version?

将提取所需的版本"强制设置为0x000A使得生成的文件在存档实用程序中也可以像在其他地方一样打开.

Forcing the "version needed to extract" to 0x000A made the generated files open as well in Archive Utility as they do everywhere else.

此问题的另一个原因是,如果使用Safari(用户代理版本> = 537)下载了zip文件,并且当您发送Content-Length标头时,您却低估了文件大小.

Another cause of this issue is if the zip file was downloaded using Safari (user agent version >= 537) and you under-reported the file size when you sent out your Content-Length header.

我们采用的解决方案是检测Safari> = 537服务器端,如果这就是您所使用的,我们将确定Content-Length大小与实际大小之间的差异(如何执行此操作取决于您的特定应用程序)在调用$ zipStream-> finish()之后,我们回显chr(0)以达到正确的长度.生成的文件在技术上是 格式错误,并且不会显示您在zip中添加的任何注释,但是所有zip程序都可以将其打开并提取文件.

The solution we employ is to detect Safari >= 537 server side and if that's what you're using, we determine the difference between the Content-Length size and the actual size (how you do this depends on your specific application) and after calling $zipStream->finish(), we echo chr(0) to reach the correct length. The resulting file is technically malformed and any comment you put in the zip won't be displayed, but all zip programs will be able to open it and extract the files.

如果您误报了Content-Length,则IE需要同样的技巧,但是与其下载不起作用的文件,不如说它不会完成下载并抛出下载中断".

IE requires the same hack if you're misreporting your Content-Length but instead of downloading a file that doesn't work, it just won't finish downloading and throws a "download interrupted".

这篇关于由ZipStream在PHP中动态创建的zip文件无法在OSX中打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆