在Cocoa中解压文件

7

我有一个压缩文件,想要提取它的内容。我应该采取什么确切的步骤来实现这一目标?是否有在Cocoa框架或Objective-C中解压文件的框架。

7个回答

7

如果你使用的是iOS系统或者不想使用NSTask等工具,我推荐使用我的库SSZipArchive

使用方法:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];

相当简单。

在提交应用到苹果商店时,我们可以使用您的库吗? - lifemoveson
也可以压缩文件夹吗? - danielreiser

6
在 Mac 上,您可以使用内置的 unzip 命令行工具,并使用 NSTask
- (void) unzip {
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* zipPath = @"myFile.zip";

    NSString* targetFolder = @"/tmp/unzipped"; //this it the parent folder
                                               //where your zip's content 
                                               //goes to (must exist)

    //create a new empty folder (unzipping will fail if any
    //of the payload files already exist at the target location)
    [fm createDirectoryAtPath:targetFolder withIntermediateDirectories:NO 
                                           attributes:nil error:NULL];


    //now create a unzip-task
    NSArray *arguments = [NSArray arrayWithObject:zipPath];
    NSTask *unzipTask = [[NSTask alloc] init];
    [unzipTask setLaunchPath:@"/usr/bin/unzip"];
    [unzipTask setCurrentDirectoryPath:targetFolder];
    [unzipTask setArguments:arguments];
    [unzipTask launch];
    [unzipTask waitUntilExit]; //remove this to start the task concurrently

}

那是一个快速而粗糙的解决方案。在实际生活中,您可能希望进行更多的错误检查,并查看unzip manpage以获取高级参数。


4

这是一份类似于Sven Driemecker答案的Swift 4版本。

func unzipFile(at sourcePath: String, to destinationPath: String) -> Bool {
    let process = Process.launchedProcess(launchPath: "/usr/bin/unzip", arguments: ["-o", sourcePath, "-d", destinationPath])
    process.waitUntilExit()
    return process.terminationStatus <= 1
}

此实现返回一个布尔值,以确定进程是否成功。即使遇到警告,也会被视为成功。
可以将返回条件更改为return process.terminationStatus == 0,以不接受警告。
有关诊断的更多详细信息,请参见解压文档
您还可以使用Pipe实例捕获进程的输出。
func unzipFile(at sourcePath: String, to destinationPath: String) -> Bool {
    let process = Process()
    let pipe = Pipe()

    process.executableURL = URL(fileURLWithPath: "/usr/bin/unzip")
    process.arguments = ["-o", sourcePath, "-d", destinationPath]
    process.standardOutput = pipe

    do {
        try process.run()
    } catch {
        return false
    }

    let resultData = pipe.fileHandleForReading.readDataToEndOfFile()
    let result = String (data: resultData, encoding: .utf8) ?? ""
    print(result)

    return process.terminationStatus <= 1
}

3

如果您只想解压文件,我建议使用NSTask来调用unzip(1)。在解压之前,将文件复制到您控制的目录(可能在/tmp中)可能是明智的。


5
/tmp文件夹是任何人都可以写入的,你无法控制它。 - user23743
Graham: 但这是一个很好的临时工作场所,可以避免覆盖现有文件夹。 - Colin Barrett
4
请使用NSTemporaryDirectory()代替/tmp,但要小心,它的行为有点像/var/tmp。 它会被清理掉,但不一定会在重新启动时清理掉。 - dreamlax

2
基于codingFriend1的方法,这里有一个更简洁的版本。
+ (void)unzip {
    NSString *targetFolder = @"/tmp/unzipped";
    NSString* zipPath = @"/path/to/my.zip";
    NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/unzip" arguments:@[@"-o", zipPath, @"-d", targetFolder]];
    [task waitUntilExit];
}

-d 指定了目标目录,如果不存在则 unzip 将创建该目录。

-o 告诉 unzip 覆盖现有文件(但不删除过时的文件,所以请注意)。

这没有错误检查等内容,但它是一个简单快速的解决方案。


1

-openFile: (NSWorkspace) 是我所知道的最简单的方法。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接