【问题标题】:Streaming ZIP file won't open in OSX流式 ZIP 文件不会在 OSX 中打开
【发布时间】:2011-09-24 09:05:26
【问题描述】:

我正在创建一个类来从 PHP 流式传输 ZIP 文件。

在 WinRAR、Windows 压缩文件夹、BetterZip 等中打开时,输出绝对没问题,但在 OSX Unarchiver 中打开时,我得到的只是一个 .cpgz 文件。

我一遍又一遍地阅读 ZIP 规范,并与我的标题交叉检查,一切看起来都很好。我确实在这里找到了另一个问题,它似乎有同样的问题,但解决方案是将我所做的“需要提取的版本”字段更改为 0x0014,并且在尝试解压缩时出现“操作不允许”错误。

我已经上传了一个示例 zip 文件,里面有一个文件夹和一个小图片:

http://www.freefilehosting.net/test_97

下面是代码的工作原理:

// File entry header
echo pack('V', 0x04034b50);
echo pack('v', 0x0014); // Version needed to extract
echo pack('v', $dir ? 0 : 0x0808); // General purpose bit flag for unknown CRC
echo pack('v', 0x00); // Compression method (store)
echo pack('V', $dts); // DOS timestamp
echo pack('V', 0x00); // CRC - empty
echo pack('V', 0x00); // Compressed data length
echo pack('V', 0x00); // Decompressed data length
echo pack('v', strlen($filename)); // Length of filename
echo pack('v', 0x00); // Length of additional data

<snip>Output raw file data</snip>

// File entry trailer
echo pack('V', 0x08074b50); // Magic
echo pack('V', $crc); // CRC generated using crc32b algo
echo pack('V', $data_size); // Compressed size
echo pack('V', $total_size); // Uncompressed size

// CDR record
echo pack('V', 0x02014b50); // Magic
echo pack('v', 0x0014); // Version created by
echo pack('v', 0x0014); // Version req'd to open
echo pack('v', 0x00); // General purpose bit
echo pack('v', 0x00); // Compression method (store)
echo pack('V', $dts); // DOS timestamp
echo pack('V', $crc); // CRC of data
echo pack('V', $data_size); // Compressed size
echo pack('V', $total_size); // Uncompressed size
echo pack('v', strlen($filename)); // Filename length
echo pack('v', 0x00); // Extra data length
echo pack('v', 0x00); // Comment length
echo pack('v', 0x00); // Start disk no.
echo pack('v', 0x00); // Internal file attributes
echo pack('V', $dir ? 16 : 32); // External file attributes
echo pack('V', $offset); // Relative offset

// End of file record
echo pack('V', 0x06054b50); // Magic
echo pack('v', 0x00); // Current disk number
echo pack('v', 0x00); // Disk containing CDR
echo pack('v', $count); // Number of entries in this CDR
echo pack('v', $count); // Total number of CDR entries
echo pack('V', $cdr_len); // Length of CDR
echo pack('V', $cdr_offset); // Offset of CDR
echo pack('v', 0x00); // Zip file comment length

【问题讨论】:

  • 显示你的一些代码。另外,OS X Unzipper 输出的是什么?
  • 正如我所提到的,OSX 解压缩器会根据“需要提取的版本”字段输出一个 .cpgz 文件或错误。代码很长,你想看哪些部分?
  • 你在打电话给ZipStream-&gt;finish()吗?
  • 我没有使用 ZipStream,我正在使用旧的 PHP pack() 自己创建 Zip 文件。我通过研究 ZIP 规范创建了这个类。

标签: php c++ macos zip


【解决方案1】:

回答我自己的问题,问题是 OSX 不喜欢两件事。 1) 将附加元数据(大小、CRC 等)附加到目录记录的末尾,因为这不是绝对必要的(但在规范内)。 2)不支持存储方式0x00(存储),文件必须至少DEFLATED才能被OSX unarchiver打开。

【讨论】:

    【解决方案2】:

    有趣的是,这不是服务器/代码问题..

    https://discussions.apple.com/thread/1446784?start=0&tstart=0

    http://www.google.co.uk/#sclient=psy&hl=en&safe=off&biw=1436&bih=784&source=hp&q=cpgz&aq=f&aqi=g3g-s1g1&aql=&oq=&pbx=1&bav=on.2,or.r_gc.r_pw.&fp=c131ccfc5fe21e40

    很多人都遇到了这个问题。

    OSX 不会为我解压缩它,引用错误:不允许操作。我必须使用终端手动解压缩。

    当你使用终端解压时,你能告诉我们输出吗?

    unzip test.zip -d test

    Shamil-Nunhucks-MacBook-Air:下载 shamil$ unzip test.zip -d test 存档:test.zip 创建:测试/测试/ 创建:测试/测试/新文件夹/ 提取:test/Test/onebit_42.png

    //线程不应该在这里 - 移动到超级用户?

    ==============================

    你需要使用:

    ob_start('ob_gzhandler')
    

    【讨论】:

    • 我看到了这些链接,我确信一定有办法绕过它。 OSX unarchiver 显然对目录记录的解释更加严格,但我确信它能够处理流式 ZIP 文件。
    • 我刚刚更新了我的答案。你能把我给你的命令的输出贴出来吗?
    • 存档:Test.zip 创建:test/Test/ 创建:test/Test/New 文件夹/ 提取:test/Test/onebit_42.png
    • 嗯,ZIP文件有完整的签名。
    • 只是为了澄清。该 Zip 文件中的“需要提取的版本”字段设置为 0x0014,这会导致“操作不允许”错误。将字段设置为 (3
    猜你喜欢
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2014-11-07
    • 2023-04-03
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多