web-dev-qa-db-ja.com

iPhone Unzipコード

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);  
}
26
TonyNeallon

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

確認するには、ファイルの最初の2バイトを確認してください。 「PK」の場合はWinZip、0x1F8Bの場合はgZipです。

これはiPhone固有なので、これを見てください iPhone SDKフォーラムディスカッション ここで miniZip について言及しています。これはWinZipファイルを処理できるようです。

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

13
schnaader

簡単な解決策が欲しかったので、ここで気に入った解決策が見つからなかったので、ライブラリを変更して自分がやりたいことを行いました。 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];
42
Sam Soffes

このコードは私にとって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に解凍することができます。

12

このコードは、.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];
4
marshad13

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

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

1
th_in_gs

zlibは.Zipファイルを開くことを意図していませんが、幸運です。zlibのcontribディレクトリには、zlibを使用して.Zipファイルを開くことができるminizipが含まれています。

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

1
Jeff M

私はiPhoneを使用していませんが、 [〜#〜] gzip [〜#〜] を参照することをお勧めします。これは、多くのプラットフォームで使用できる非常に移植性の高いオープンソースのZipライブラリです。

0
SmacL