【发布时间】:2010-12-28 01:00:34
【问题描述】:
是否存在与 Java 包 java.util.zip 中包含的类等效的 Objective-C 类?
执行 CLI 命令是唯一的选择吗?
【问题讨论】:
标签: objective-c cocoa zip archive
是否存在与 Java 包 java.util.zip 中包含的类等效的 Objective-C 类?
执行 CLI 命令是唯一的选择吗?
【问题讨论】:
标签: objective-c cocoa zip archive
有一个 zip 框架,http://code.google.com/p/zip-framework/,但它似乎处于早期(0.1 版)阶段。
cocoadev 上的其他答案:http://cocoadev.com/ZipArchiveLibraryForCocoa
从那里得到一个答案:ZipKit,https://github.com/kolpanic/ZipKit
【讨论】:
查看http://code.google.com/p/ziparchive/。这是一个用于压缩文件的类。 Google 是您的朋友!
【讨论】:
除了在您自己的进程中读取和写入 zip 存档之外,使用 NSTask 运行 zip 和 unzip 也没什么丢人的。
【讨论】:
查看zipzap,我的快速 zip 文件 I/O 库。
【讨论】:
从 iOS8/OSX10.10 开始,有一种内置方法可以使用 NSFileCoordinatorReadingOptions.ForUploading 创建 zip 存档。一个没有任何非 Cocoa 依赖项的创建 zip 档案的简单示例:
public extension NSURL {
/// Creates a zip archive of the file/folder represented by this URL and returns a references to the zipped file
///
/// - parameter dest: the destination URL; if nil, the destination will be this URL with ".zip" appended
func zip(dest: NSURL? = nil) throws -> NSURL {
let destURL = dest ?? self.URLByAppendingPathExtension("zip")
let fm = NSFileManager.defaultManager()
var isDir: ObjCBool = false
let srcDir: NSURL
let srcDirIsTemporary: Bool
if let path = self.path where self.fileURL && fm.fileExistsAtPath(path, isDirectory: &isDir) && isDir.boolValue == true {
// this URL is a directory: just zip it in-place
srcDir = self
srcDirIsTemporary = false
} else {
// otherwise we need to copy the simple file to a temporary directory in order for
// NSFileCoordinatorReadingOptions.ForUploading to actually zip it up
srcDir = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(NSUUID().UUIDString)
try fm.createDirectoryAtURL(srcDir, withIntermediateDirectories: true, attributes: nil)
let tmpURL = srcDir.URLByAppendingPathComponent(self.lastPathComponent ?? "file")
try fm.copyItemAtURL(self, toURL: tmpURL)
srcDirIsTemporary = true
}
let coord = NSFileCoordinator()
var error: NSError?
// coordinateReadingItemAtURL is invoked synchronously, but the passed in zippedURL is only valid
// for the duration of the block, so it needs to be copied out
coord.coordinateReadingItemAtURL(srcDir, options: NSFileCoordinatorReadingOptions.ForUploading, error: &error) { (zippedURL: NSURL) -> Void in
do {
try fm.copyItemAtURL(zippedURL, toURL: destURL)
} catch let err {
error = err as NSError
}
}
if srcDirIsTemporary { try fm.removeItemAtURL(srcDir) }
if let error = error { throw error }
return destURL
}
}
public extension NSData {
/// Creates a zip archive of this data via a temporary file and returns the zipped contents
func zip() throws -> NSData {
let tmpURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(NSUUID().UUIDString)
try self.writeToURL(tmpURL, options: NSDataWritingOptions.DataWritingAtomic)
let zipURL = try tmpURL.zip()
let fm = NSFileManager.defaultManager()
let zippedData = try NSData(contentsOfURL: zipURL, options: NSDataReadingOptions())
try fm.removeItemAtURL(tmpURL) // clean up
try fm.removeItemAtURL(zipURL)
return zippedData
}
}
【讨论】:
将answer of @marcprux 翻译成Objective-C。如果这对您有用,请相信他的回答:
NSURL+Compression.h
#import <Foundation/Foundation.h>
@interface NSURL (NSURLExtension)
- (NSURL*)zip;
@end
NSURL+Compression.m
#import "NSURL+Compression.h"
@implementation NSURL (NSURLExtension)
-(NSURL*)zip
{
BOOL isDirectory;
BOOL hasTempDirectory = FALSE;
NSURL* sourceURL;
NSFileManager* fileManager = [NSFileManager defaultManager];
BOOL fileExists = [fileManager fileExistsAtPath:self.path isDirectory:&isDirectory];
NSURL* destinationURL = [self URLByAppendingPathExtension:@"zip"];
if(fileExists && isDirectory)
{
sourceURL = self;
}
else
{
sourceURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:[[NSUUID UUID] UUIDString]];
[fileManager createDirectoryAtURL:sourceURL withIntermediateDirectories:TRUE attributes:nil error:nil];
NSString* pathComponent = self.lastPathComponent ? self.lastPathComponent : @"file";
[fileManager copyItemAtURL:self toURL:[sourceURL URLByAppendingPathComponent:pathComponent] error:nil];
hasTempDirectory = TRUE;
}
NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] init];
[fileCoordinator coordinateReadingItemAtURL:sourceURL options:NSFileCoordinatorReadingForUploading error:nil byAccessor:^(NSURL* zippedURL)
{
[fileManager copyItemAtURL:zippedURL toURL:destinationURL error:nil];
}];
if(hasTempDirectory)
{
[fileManager removeItemAtURL:sourceURL error:nil];
}
return destinationURL;
}
@end
NSData+Compression.h
#import <Foundation/Foundation.h>
@interface NSData (NSDataExtension)
- (NSData*)zip;
@end
NSData+Compression.m
#import "NSData+Compression.h"
#import "NSURL+Compression.h"
@implementation NSData (NSDataExtension)
// Creates a zip archive of this data via a temporary file and returns the zipped contents
// Swift to objective c from https://stackoverflow.com/a/32723162/
-(NSData*)zip
{
NSURL* temporaryURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:[[NSUUID UUID] UUIDString]];
[self writeToURL:temporaryURL options:NSDataWritingAtomic error:nil];
NSURL* zipURL = [temporaryURL zip];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSData* zippedData = [NSData dataWithContentsOfURL:zipURL options:NSDataReadingMapped error:nil];
[fileManager removeItemAtURL:temporaryURL error:nil];
[fileManager removeItemAtURL:zipURL error:nil];
return zippedData;
}
@end
如果有任何改进,请告诉我。
【讨论】: