2011-06-15 3 views
1

私は、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]; 

ジッパーのドキュメントが真実を言っていたことを期待して:デフォルトでは

、ジッパーは (カレントディレクトリに対して)

完全なパスを格納します

しかし、これは期待どおりに機能しませんでした。 -jと-pおよび-rの設定を調整するだけで、上記の問題がさまざまな組み合わせで生成されます。

質問:私のようなディレクトリのセットを取ることができますどのように

  • /いくつか/ロング/パス/ SUB2/file1を/some/long/path/sub1/file1.txt

.txtファイルとその内容

    あるジッパーにそれらを圧縮ジップの機微上の任意のアドバイスのための3210

/sub2/file1.txt

  • /sub1/file1.txt感謝。私は追加するのを忘れ

    ----- EDIT

    もうひとつは、渡された元のディレクトリが「パス」であるので、望ましい結果はまた、私の心に予想される結果であるということです。代わりに前のタスクを起動する

    [[NSFileManager defaultManager] changeCurrentDirectoryPath:path]; 
    

    使用-[NSTask setCurrentDirectoryPath:]

    答えて

    2

    これは、普遍的解決策ではありませんが、私は解決策は、未知の内容(すなわち、混合のファイル/フォルダ/の単一ディレクトリの使用しますバンドル)は、単にディレクトリ全体を一度に圧縮するのではなく、ディレクトリの内容を列挙し、それらを個別に引数として追加することです。具体的に

    + (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); 
    } 
    

    は再び、私はこれは防弾で何の主張をしない(と改善を大好きだ)が、それは仕事がで正しく任意の単一のフォルダをビュンありません。

    2

    。例えば:それも複数のディレクトリを処理しないことに

    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]; 
    … 
    
    +0

    これは素晴らしいソリューションのようです。私はどのように私はタスク固有のディレクトリメソッドを見逃しているのかわかりません。私は別のルートを見つけることができたので、私はこれをテストしていない。私がこれについて持っているもう一つの質問と私が提供する解決策については、もし二つのディレクトリが共通の親を持たないならどうでしょうか? – SG1

    +0

    @ SG1ディレクトリに共通の親がない場合、 'zip'コマンドラインユーティリティがそれを行うことはできません。ディレクトリをいくつかのディレクトリにコピーすることはできますが、それは理想的ではありません。 –

    関連する問題