26

iPhone でファイルまたはディレクトリを解凍するためのコードを書こうとして本当に行き詰まりました。

以下は、単純なテキスト ファイルを解凍するために使用しているサンプル コードです。

ファイルを解凍しますが、破損しています。

(void)loadView {

    NSString *DOCUMENTS_FOLDER = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *path = [DOCUMENTS_FOLDER stringByAppendingPathComponent:@"sample.zip"];

    NSString *unzipeddest = [DOCUMENTS_FOLDER stringByAppendingPathComponent:@"test.txt"];  

    gzFile file = gzopen([path UTF8String], "rb");

    FILE *dest = fopen([unzipeddest UTF8String], "w");

    unsigned char buffer[CHUNK];

    int uncompressedLength = gzread(file, buffer, CHUNK);

    if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength ||     ferror(dest)) {
        NSLog(@"error writing data");
    }
    else{

    }

    fclose(dest);
    gzclose(file);  
}
4

8 に答える 8

41

簡単な解決策が欲しかったのですが、ここで気に入ったものが見つからなかったので、ライブラリを変更して、やりたいことを行いました。SSZipArchiveが役立つ場合があります。(ちなみにzipファイルも作成できます。)

使用法:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];
于 2010-07-21T23:20:09.947 に答える
13

「sample.zip」は本当に gZip で作成されたものですか? .zip 拡張子は通常、WinZip で作成されたアーカイブに使用されます。これらは zLib を使用して解凍することもできますが、ヘッダーを解析して他のルーチンを使用する必要があります。

確認するには、ファイルの最初の 2 バイトを見てください。'PK' なら WinZip、0x1F8B なら gZip です。

これは iPhone 固有のものであるため、miniZip について言及されているこのiPhone SDK フォーラム ディスカッションを参照てください。これで WinZip ファイルを扱えるようです。

しかし、それが本当に WinZip ファイルである場合は、WinZip の仕様を確認して、自分でファイルを解析してみてください。基本的には、いくつかのヘッダー値を解析し、圧縮されたストリームの位置を探し、zLib ルーチンを使用して解凍する必要があります。

于 2009-01-05T12:58:23.847 に答える
12

このコードはgzipでうまく機能しました:

データベースは次のように準備されました:gzip foo.db

キーはgzread()をループしていました。上記の例では、最初のCHUNKバイトのみを読み取ります。

#import <zlib.h>
#define CHUNK 16384


  NSLog(@"testing unzip of database");
  start = [NSDate date];
  NSString *zippedDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"foo.db.gz"];
  NSString *unzippedDBPath = [documentsDirectory stringByAppendingPathComponent:@"foo2.db"];
  gzFile file = gzopen([zippedDBPath UTF8String], "rb");
  FILE *dest = fopen([unzippedDBPath UTF8String], "w");
  unsigned char buffer[CHUNK];
  int uncompressedLength;
  while (uncompressedLength = gzread(file, buffer, CHUNK) ) {
    // got data out of our file
    if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
      NSLog(@"error writing data");
    }
  }
  fclose(dest);
  gzclose(file);
  NSLog(@"Finished unzipping database");

ちなみに、私は77秒で33MBを130MBに解凍できます。つまり、非圧縮/秒で約1.7MBです。

于 2009-08-16T12:35:23.810 に答える
4

このコードは、任意の .zip ファイルをアプリ ドキュメント ディレクトリに解凍し、アプリ リソースからファイルを取得します。

self.fileManager = [NSFileManager defaultManager];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSLog(@"document directory path:%@",paths);

self.documentDirectory = [paths objectAtIndex:0];

NSString *filePath = [NSString stringWithFormat:@"%@/abc", self.documentDirectory];

NSLog(@"file path is:%@",filePath);

NSString *fileContent = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"data.zip"];


NSData *unzipData = [NSData dataWithContentsOfFile:fileContent];

[self.fileManager createFileAtPath:filePath contents:unzipData attributes:nil];

// here we go, unzipping code

ZipArchive *zipArchive = [[ZipArchive alloc] init];

if ([zipArchive UnzipOpenFile:filePath])
{
    if ([zipArchive UnzipFileTo:self.documentDirectory overWrite:NO])
    {
        NSLog(@"Archive unzip success");
        [self.fileManager removeItemAtPath:filePath error:NULL];
    }
    else
    {
        NSLog(@"Failure to unzip archive");
    }
}
else
{
    NSLog(@"Failure to open archive");
}
[zipArchive release];
于 2011-05-20T11:35:44.750 に答える
1

任意の zip ファイルを解凍するのは非常に困難です。これは複雑なファイル形式であり、ファイルの内部で使用される可能性のあるさまざまな圧縮ルーチンが多数存在する可能性があります。Info-ZIP には、自由にライセンス可能なコード ( http://www.info-zip.org/UnZip.html ) があり、ハッキングを行うことで iPhone で動作させることができますが、API は率直に言って恐ろしいものです。コマンドライン引数を UnZIP の実行をシミュレートする偽の「メイン」に渡します (公平を期すために、コードはそもそもこのように使用されるように設計されていなかったため、ライブラリ機能は後で追加されました)。

解凍しようとしているファイルがどこから来ているかを制御できる場合は、ZIP の代わりに別の圧縮システムを使用することを強くお勧めします。その柔軟性と遍在性により、ファイルのアーカイブを個人間でやり取りするには最適ですが、自動化するのは非常に厄介です。

于 2009-01-05T13:09:04.263 に答える
1

zlib は .zip ファイルを開くためのものではありませんが、運がよければ: zlib の contrib ディレクトリには、zlib を使用して .zip ファイルを開くことができる minizip が含まれています。

SDK にバンドルされていない可能性がありますが、バンドルされているバージョンの zlib を使用できる可能性があります。zlib ソースのコピーを入手して、contrib/minizip を調べてください。

于 2009-01-05T13:16:55.247 に答える
0

私は iPhone を使用していませんが、多くのプラットフォームで利用できる移植性の高いオープン ソースの zip ライブラリであるGZIPを参照してください。

于 2009-01-05T12:45:40.177 に答える
-5

iPhoneシミュレーターでこれをテストして運が良かった:

NSArray *paths = 
   NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *saveLocation = 
   [documentsDirectory stringByAppendingString:@"myfile.zip"];

NSFileManager* fileManager = [NSFileManager defaultManager];

if ([fileManager fileExistsAtPath:saveLocation]) {
    [fileManager removeItemAtPath:saveLocation error:nil];

}

NSURLRequest *theRequest = 
             [NSURLRequest requestWithURL:
                [NSURL URLWithString:@"http://example.com/myfile.zip"]
             cachePolicy:NSURLRequestUseProtocolCachePolicy
             timeoutInterval:60.0];    

NSData *received = 
             [NSURLConnection sendSynchronousRequest:theRequest 
                              returningResponse:nil error:nil];    

if ([received writeToFile:saveLocation atomically:TRUE]) {      
    NSString *cmd = 
       [NSString stringWithFormat:@"unzip \"%@\" -d\"%@\"", 
       saveLocation, documentsDirectory];       

    // Here comes the magic...
    system([cmd UTF8String]);       
}

zlibをいじるよりも簡単に見えます...

于 2009-11-12T00:41:03.007 に答える