如何在Pharo中创建Zip文件并写入磁盘?
在Pharo中创建Zip文件并写入磁盘
基于MemoryStore的实现方案
你想用MemoryStore先构建文件结构再压缩的思路非常合理,这样能避免在磁盘上创建临时文件,直接在内存里完成结构组装再输出Zip包。下面是完善后的可运行代码,我还补充了一些细节让它更实用:
"1. 在内存中构建完整的文件目录结构" root := FileSystem memory root ensureCreateDirectory. root / 'sample.txt' writeStreamDo: [ :stream | stream << String loremIpsum ]. "可以按需添加子目录和更多文件" (root / 'docs' / 'notes') ensureCreateDirectory. (root / 'docs' / 'notes' / 'todo.txt') writeStreamDo: [ :stream | stream << '- 完善Zip打包逻辑 - 测试不同编码的文件' ]. "2. 创建ZipArchive并将内存文件添加进去" archive := ZipArchive new. root allChildren select: #isFile thenDo: [ :eachFile | eachFile readStreamDo: [ :readStream | "用相对路径替代内存文件系统的绝对路径,让Zip包内的结构更清晰" archive addString: readStream contents as: (eachFile relativeTo: root) pathString ] ]. "3. 将最终的Zip文件写入磁盘指定位置" FileLocator desktop / 'my_memory_built_archive.zip' writeStreamDo: [ :finalStream | archive writeTo: finalStream binary ]. "记得清理资源,避免内存泄漏" archive close.
关键细节说明
- 路径优化:原代码里用
each fullName会得到内存文件系统的绝对路径(比如/sample.txt),换成eachFile relativeTo: root能生成相对于根目录的路径,让Zip包内的文件结构更符合预期。 - 二进制流写入:写入磁盘时一定要指定
binary模式,不然文本编码转换可能会破坏Zip文件的结构,导致无法正常解压。 - 资源清理:使用完
ZipArchive后调用close方法,确保相关流资源被正确释放。
更简洁的写法:直接添加FileReference
其实Pharo的ZipArchive支持直接添加FileReference,内存文件系统里的文件也适用,代码可以更简洁直观:
root := FileSystem memory root ensureCreateDirectory. root / 'sample.txt' writeStreamDo: [ :s | s << String loremIpsum ]. archive := ZipArchive new. root allChildren select: #isFile thenDo: [ :file | archive addFile: file as: (file relativeTo: root) pathString ]. (FileLocator documents / 'quick_archive.zip') writeStreamDo: [ :stream | archive writeTo: stream binary ]. archive close.
这种写法省去了手动处理读流的步骤,代码可读性更高。
内容的提问来源于stack exchange,提问作者Peter Uhnak
相关产品推荐
相关产品推荐

