【问题标题】:Best way to loop through a lot of files and zip each one separately?循环浏览大量文件并分别压缩每个文件的最佳方法?
【发布时间】:2011-06-29 22:02:05
【问题描述】:

我需要遍历一组相对较大的文件 (> 5000),依次将每个文件单独压缩并上传到服务器(而不是目录或文件组)。

我最大的问题是要知道在易于实施和性能方面哪种方式是进行压缩的最佳方式。我认为必须有一个标准的 Cocoa 框架来处理显然是一个非常常见的需求,但似乎没有任何这样的框架。到目前为止我发现的其他建议和方法:

  • zip.framework at code.google.com,“这是一个可可框架,用于轻松列出、读取和写入 zip 文件。这个框架的主要目的是通过提供一个原生的来防止你在应用程序中使用命令行实用程序。 Cocoa interface” - 似乎很多人都找到了这个链接(但我没有注意到之前有人真正使用过它!)
  • ziparchive 也在 code.google.com -“基于开源代码‘MiniZip’”。
  • 关于使用NSTask 调用命令行实用程序(例如ditto)的建议很常见,例如在此CocoaDev question 中,但我不喜欢必须这样做的想法
  • 同样,这里有人建议 NSTask 调用 zipunzip - 但是这个 posting 说“唯一的问题是当文件解压缩时, Mac 标头已被剥离,因此 Mac OS 无法识别该文件!!(即我压缩了一个应用程序,它从文件中剥离了“appl”。当我解压缩它时,它无法使用。”
  • 某人的框架叫 ZipKit here
  • Another CocoaDev question 讨论了几种方法,例如为 C++ 归档代码创建包装器,为 zlibminizip 创建 C 包装器(minizip 是围绕 zlib 构建的)等
  • 关于NSDataCategory的东西(没看懂)
  • 来自 www.feedface.com 的开源漫画/漫画书阅读器 (!),名为 FFView,它有自己独立的 archiving framework

压缩文件需要在 Windows 中解压。

拜托,我希望有人对满足我类似要求的解决方案有实际经验。正如你所看到的,我已经找到了很多链接,所以只是另一个链接到另一个框架/方法,而没有实际表明它适用于我的问题的东西不会真的很有帮助。

谢谢!

【问题讨论】:

  • 您应该考虑将最终使用的任何方法包装在 NSOperation 对象中,以便系统可以有效地处理并发性以获得最佳性能。

标签: objective-c cocoa macos


【解决方案1】:

这就是我认为的“正确的 Cocoa 方式”。你可能不喜欢它,但它可以工作,它不需要外部框架,而且只需要很少的代码。

将 shell 脚本添加到您的应用程序包中,zipmany.sh

#!/bin/bash
set -e
SRC="$1"
DEST="$2"
cd "$SRC"
for FILE in $(find . -not -name '.*' -a type f)
do
    zip -jD "$DEST"/"$FILE".zip "$FILE"
done

然后,在 Cocoa 中,

NSString *script = [[NSBundle mainBundle] pathForResource:@"zipmany" ofType:@"sh"];
NSTask *task = [[NSTask alloc] init];
[task setArguments:[NSArray arrayWithObjects:@"zipmany.sh", srcDir, destDir, nil]];
[task launch];
[task waitUntilExit];
if ([task terminationReason] == ATASK_SUCCESS_VALUE)
    succeeded;
else
    failed;

您可能对这种事情犹豫不决,但将这种任务委托给单独的流程是稳健且相当标准的。

如果文件名可以有空格,你将不得不稍微改变一下 shell 脚本;我考虑编写“安全”版本,但这更具可读性。您还可以通过回显脚本的输出来制作进度条以供应用程序读取。

waitUntilExit 的调用将导致您的应用程序冻结或“沙滩球”,除非您在单独的线程中运行整个事情,或者对 Unix IPC 有足够的了解来处理 SIGCHLD。

【讨论】:

  • 我现在就试试这个,谢谢...但是如果这是“正确的 Cocoa 方式”,为什么会有这么多替代方案?
  • “正确的可可方式”本质上是主观的。但如果有人问我,“你能把一千个文件压缩成单独的 zip 文件吗?”我的第一个想法是,“啊,我可以在五分钟内用一个 shell 脚本做到这一点。”当我们已经有了像 shell 脚本这样的好工具时,用框架来做这件事似乎是一种不必要的复杂化。
  • 谢谢!我的问题背后的主要想法是,“嗯......他们知道我不知道什么?”我本能地希望核心代码中的所有内容都可以在一个地方维护,并且可以作为一个整体进行检查和编译,但没有具体的反对意见。
  • 我认为框架的主要用途是在 zip 文件中列出对象,或者读取单个文件的内容。例如,许多游戏都使用它们的资产来做到这一点。但是压缩文件的交互性较差。
【解决方案2】:

如果您使用的是 Linux,我会使用带有一些工具(zip、lftp 和 find)的 shell 脚本。然后,您可以压缩所有文件并上传,然后只需运行脚本即可。 对于这样的解决方案,我可以为您提供一些帮助。

还是要求您使用您提到的库在 C 或 C++ 中实现压缩工具?

更新

为什么 Unicode 与您的问题相关?因为文件名?

您可以通过编写包装器将文件名转换为 latin1 编码,并与压缩文件一起存储一个小文本文件。

关于效率,也许你可以做一些研究,找出最好的算法是什么,然后寻找支持它的库。据我所知,zip 压缩是基于 lz77 或 lzw:你甚至可以在某个地方查找它并自己实现它, 如果你想压缩单个文件应该不是很困难,因为你只 需要实现基本算法并将其应用于字节流。 参见例如http://en.pudn.com/downloads33/sourcecode/zip/detail106575_en.html, http://rosettacode.org/wiki/LZW_compression

【讨论】:

  • 我正在使用 Cocoa/Objective-C for Mac OS X 构建一个应用程序。该应用程序将执行压缩。
  • 啊,好吧,对不起,我帮不了你太多,因为我从未使用过 MaxOS 和 Objective-C。只有一个(相当自发的)问题:你为什么不试试你已经找到的图书馆之一?我想它归结为编写一个小型测试程序并将其链接到库。那么,如果性能满足您的需求,那么您已经很遥远了。
  • 谢谢。是的,我可以尝试其中的一个或多个,但从我的角度来看,有两个问题。 1. 有这么多的可能性,我想我必须至少尝试一些才能感觉到我已经为此付出了任何努力 2. 即便如此,在代码消失之前,我仍然可能不会发现一个特定的问题投入生产,例如文件大小、unicode 字符、文件类型等。因此,以前经历过这些的人可能非常有价值。
猜你喜欢
  • 2014-11-09
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 2017-06-02
  • 1970-01-01
相关资源
最近更新 更多