Подтвердить что ты не робот

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);  
}
4b9b3361

Ответ 1

Действительно ли "sample.zip" был создан с помощью gZip? Расширение .zip обычно используется для архивов, созданных WinZip. Они также могут быть распакованы с помощью zLib, но вам придется анализировать заголовок и использовать другие процедуры.

Чтобы проверить, просмотрите первые два байта файла. Если это "PK", это WinZip, если он 0x1F8B, он gZip.

Поскольку это конкретный iPhone, посмотрите на это обсуждение форума iPhone SDK, где miniZip. Похоже, что это может обрабатывать файлы WinZip.

Но если это действительно файл WinZip, вы должны посмотреть на спецификацию WinZip и попытаться самостоятельно проанализировать файл. В основном он должен анализировать некоторые значения заголовков, искать сжатую позицию потока и использовать подпрограммы zLib для ее распаковки.

Ответ 2

Я хотел простое решение и не нашел тот, который мне понравился, поэтому я модифицировал библиотеку, чтобы делать то, что хотел. Вы можете найти 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];

Ответ 3

Этот код хорошо работал у меня для 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");

Кстати, я могу разархивировать 33 МБ в 130 МБ за 77 секунд или около 1,7 МБ без сжатия/секунды.

Ответ 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];

Ответ 5

Очень сложно распаковать любой произвольный zip файл. Это сложный формат файла, и есть потенциально много различных подпрограмм сжатия, которые могли быть использованы внутри файла. Info-ZIP имеет некоторый свободно распространяемый код, чтобы сделать это (http://www.info-zip.org/UnZip.html), который можно заставить работать на iPhone с некоторым хакером, но API откровенно ужасен - он включает передачу аргументов командной строки поддельной "основной", которая имитирует работу UnZIP (справедливости ради, потому что их код никогда не был предназначен для такого использования в первую очередь, впоследствии функциональность библиотеки была закреплена болтами).

Если у вас есть контроль над тем, куда идут файлы, которые вы пытаетесь распаковать, я настоятельно рекомендую использовать другую систему сжатия вместо ZIP. Это гибкость и вездесущность делают его отличным для передачи архивов файлов по личному обращению, но очень неудобно автоматизировать.

Ответ 6

zlib не предназначен для открытия ZIP файлов, но вам повезло: каталог zlib contrib включает в себя minizip, который может использовать zlib для открытия .zip файлов.

Возможно, он не связан в SDK, но вы, вероятно, можете использовать связанную с ним версию zlib. Возьмите копию источника zlib и посмотрите в contrib/minizip.

Ответ 7

Я не использовал iPhone, но вы можете посмотреть GZIP, который является очень переносимым с открытым исходным кодом библиотека доступна для многих платформ.

Ответ 8

Мне повезло проверить это на симуляторе 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...