如何在 Perl 中创建 Zip 存档?
在过滤我想要包含的文件列表后,我需要创建一个 Zip 存档。 我最好希望该模块能够在 Windows 和 Linux 中工作。
由于我需要过滤文件列表,因此我真的不想使用外部程序。 我也不想引入外部依赖项,这样我就可以将脚本编译成 Windows 上的单个可执行文件(使用 ActiveState PDK )。
我已经尝试过的
到目前为止,我已经使用Archive::Zip 在 CPAN 上找到,但它有一个重大错误在使用非 ASCII 文件名的 Windows 计算机上:文件名在存档中会被损坏,因为它们不会被转换为 unicode。
有一个提交的错误报告,但还没有'超过 10 个月没有更新,并且在模块文档中,开发人员没有提供任何帮助(“修复您的计算机或摆脱 Windows”之类的)。
更新:
感谢 brian 和 Alan Haggai Alavi 的澄清,似乎人们对 Archive::Zip 投入了足够的爱,以便尽快解决这些错误,并最终在 Windows 中拥有一个功能齐全的 zip 模块。
I need to create a Zip archive after filtering the list of files I want to include. Preferably I'd like the module to work in both Windows and Linux.
Since I need to filter the list of files, I don't really want to to use an external program. I'd rather not introduce external dependencies either so I can compile the script into a single executable on Windows (using ActiveState PDK).
What I already tried
Until now I've used Archive::Zip found on CPAN but it has a major bug on Windows machine that use non-ASCII filenames: the filenames get corrupted in the archive as they don't get translated into unicode.
There is a bug report filed for that but it hasn't been updated in over 10 months and in the module documentation the developer is rather unhelpful (of the "fix your computer or get rid of Windows" kind).
Update:
Thanks to the clarifications from brian and Alan Haggai Alavi it seems that enough love is being put in Archive::Zip
to get these bugs out soon and finally have a fully functioning zip module in Windows.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尽管模块文档说了一些关于 Windows 的愚蠢的事情,但当前的维护者是 Adam Kennedy,就是为您带来 Strawberry Perl。 他绝对不是反对Windows。 他十月份发布了一个版本,所以他们正在努力。 还有 Perl 基金会 向 修复 Archive::Extract bugs。您提到的 bug,RT 35334:通过 Archive::Zip 进行文件名编码,也许只是需要有人向它表达一些爱意。 那可能是你。 人们解决困扰他们的问题,所以也许对这个模块感兴趣的人还没有需要这个。
该模块存在问题,自从我在几个项目中使用它以来,我一直在跟踪它的进展。 最近已经好多了,当然需要一些爱。 有时开源意味着帮助解决您遇到的问题。 我知道这并不能帮助您立即解决问题,但这就是我认为除了
system()
调用之外您将完成此任务的方式。Although the module documentation says some stupid things about Windows, the current maintainer is Adam Kennedy, the same guy who brought you Strawberry Perl. He's definitely not anti-Windows. He released a version October, so they are working on it. There's also an open grant from The Perl Foundation to fix Archive::Extract bugs.The bug you mention, RT 35334: Filename Encoding by Archive::Zip, maybe just needs someone to show it some love. That could be you. People solve the problems that bother them, so maybe nobody interested in the module needs this just yet.
The module has had problems, and I've been following its progress since I use it in a couple projects. It has gotten a lot better recently and can certainly use some love. Sometimes open source means helping to fix the problems that you encounter. I know this doesn't help you solve your problem immediately, but that's how I think you're going to get this done aside from
system()
calls.最近,通过在 Windows 下添加 Unicode 文件名支持,上述错误已得到解决。 包含该修复程序的版本将在一周内在 CPAN 中发布。
The above said bug has been solved very lately by the addition of Unicode filename support under Windows. A release featuring the fix will be available in CPAN within a week.
您可以尝试标准发行版 Archive::Extract。 它可能并不比 Archive::Zip 好多少,但文档说,如果出现问题,它会在幕后尝试使用系统上的命令行工具来解压缩文件。 这在 Unix 上可能是最强大的,但 Windows 有一个 zip 存档实用程序,并且它应该可以通过命令行访问。 另外,Archive::Extract 可以处理许多其他类型的压缩(理论上)。
当然,Archive::Extract 可能只是简单地找出文件使用的压缩类型,然后将其传递给适当的其他库,该库可能是 Archive::Zip。
您也可以尝试 IO::Uncompress::Unzip 及其对应的 < a href="http://perldoc.perl.org/IO/Compress/Zip.html" rel="nofollow noreferrer">IO::Compress::Zip,用于解压缩、读取和重新压缩。 如果绝对有必要的话。 再说一次,我不知道它们会工作得有多好,但它们都是标准库的一部分。
You could try the standard-distribution Archive::Extract. It may not be any better than Archive::Zip, but the documentation says that, if there are problems, it goes under the hood to try to use command-line tools on your system to unzip the file. This is probably most robust on Unix, but Windows has a zip archive utility, and it should be accessible via the command line. Plus, Archive::Extract can handle many other types of compression (theoretically).
Of course, it may turn out that Archive::Extract simply figures out what kind of compression the file uses and then passes it to the appropriate other library, which might be Archive::Zip.
You might also try IO::Uncompress::Unzip and it's counterpart, IO::Compress::Zip, for just unzipping, reading, and rezipping. If absolutely necessary. Again, I don't know how much better these will work, but they are all part of the standard library.