我正在使用NSTask从我的应用程序中执行zip命令。它作为参数传递了一些指向要压缩的文件/文件夹的路径。
问题是如果没有-j选项,最终的zip会以zip内的荒谬文件路径结束,(例如“/ private / var / folders / A5 / A5CusLQaEo4mop-reb-SYE +++ TI / -Tmp- /9101A216-5A6A-4CD6-A477-E4B86E007476-51228-00014BCB9514323F/myfile.rtf“)。但是,如果我添加-j选项,那么如果嵌套文件夹内任何位置的任何文件都有
,我会不断遇到名称冲突我在尝试NSTask之前尝试设置路径:
[[NSFileManager defaultManager] changeCurrentDirectoryPath:path];
希望zip的文档说实话:
默认情况下,zip会存储完整路径 (相对于当前目录)
但这并没有像预期的那样奏效。调整-j和-p和-r的设置只会以不同的组合产生上述问题。
问题:
如何获取一组目录,如
并将它们压缩成拉链,其内容为
感谢您对zip的微妙之处提出任何建议。
----- EDIT
我忘记添加的另一件事是传递的原始目录是“路径”,因此我想到的结果也是预期的结果。
答案 0 :(得分:2)
而不是
[[NSFileManager defaultManager] changeCurrentDirectoryPath:path];
在启动任务之前使用-[NSTask setCurrentDirectoryPath:]
。例如:
NSString *targetZipPath = @"/tmp/foo.zip";
NSArray *args = [NSArray arrayWithObjects:@"-r", targetZipPath,
@"sub1", @"sub2", nil];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/zip"];
[task setArguments:args];
// set path to be the parent directory of sub1, sub2
[task setCurrentDirectoryPath:path];
…
答案 1 :(得分:2)
这不是一个通用的解决方案,因为它不能很好地处理多个目录,但我用于未知内容的单个目录(即混合文件/文件夹/包)的解决方案是枚举内容目录并将它们作为zip的参数单独添加,而不是简单地一次性压缩整个目录。
具体做法是:
+ (BOOL)zipDirectory:(NSURL *)directoryURL toArchive:(NSString *)archivePath;
{
//Delete existing zip
if ( [[NSFileManager defaultManager] fileExistsAtPath:archivePath] ) {
[[NSFileManager defaultManager] removeItemAtPath:archivePath error:nil];
}
//Specify action
NSString *toolPath = @"/usr/bin/zip";
//Get directory contents
NSArray *pathsArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[directoryURL path] error:nil];
//Add arguments
NSMutableArray *arguments = [[[NSMutableArray alloc] init] autorelease];
[arguments insertObject:@"-r" atIndex:0];
[arguments insertObject:archivePath atIndex:0];
for ( NSString *filePath in pathsArray ) {
[arguments addObject:filePath]; //Maybe this would even work by specifying relative paths with ./ or however that works, since we set the working directory before executing the command
//[arguments insertObject:@"-j" atIndex:0];
}
//Switch to a relative directory for working.
NSString *currentDirectory = [[NSFileManager defaultManager] currentDirectoryPath];
[[NSFileManager defaultManager] changeCurrentDirectoryPath:[directoryURL path]];
//NSLog(@"dir %@", [[NSFileManager defaultManager] currentDirectoryPath]);
//Create
NSTask *task = [[[NSTask alloc] init] autorelease];
[task setLaunchPath:toolPath];
[task setArguments:arguments];
//Run
[task launch];
[task waitUntilExit];
//Restore normal path
[[NSFileManager defaultManager] changeCurrentDirectoryPath:currentDirectory];
//Update filesystem
[[NSWorkspace sharedWorkspace] noteFileSystemChanged:archivePath];
return ([task terminationStatus] == 0);
}
同样,我没有声称这是防弹(并且会喜欢改进),但它确实能够正确压缩任何单个文件夹。