Pregunta

Realmente atascado en tratar de escribir código para descomprimir un archivo o directorio en el iPhone.

A continuación se muestra un código de muestra que estoy usando para intentar descomprimir un archivo de texto simple.

Descomprime el archivo pero está dañado.

(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);  
}
¿Fue útil?

Solución

Tiene " sample.zip " Realmente ha sido creado con gZip? La extensión .zip generalmente se usa para archivos creados por WinZip. También se pueden descomprimir usando zLib, pero tendría que analizar el encabezado y usar otras rutinas.

Para verificar, eche un vistazo a los dos primeros bytes del archivo. Si es 'PK', es WinZip, si es 0x1F8B, es gZip.

Debido a que esto es específico de iPhone, eche un vistazo a este discusión del foro del SDK de iPhone donde se menciona miniZip . Parece que esto puede manejar archivos WinZip.

Pero si realmente es un archivo WinZip, debería echar un vistazo a la especificación WinZip e intenta analizar el archivo tú mismo. Básicamente, debería analizar algunos valores de encabezado, buscar la posición de flujo comprimido y usar rutinas zLib para descomprimirlo.

Otros consejos

Quería una solución fácil y no encontré una que me gustara aquí, así que modifiqué una biblioteca para hacer lo que quería. Puede encontrar SSZipArchive útil. (También puede crear archivos zip por cierto).

Uso:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];

Este código funcionó bien para mí para gzip:

la base de datos se preparó así:     gzip foo.db

la clave estaba en bucle sobre el gzread (). El ejemplo anterior solo lee los primeros bytes 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");

Por cierto, puedo descomprimir 33MB en 130MB en 77 segundos o aproximadamente 1.7 MB sin comprimir / segundo.

Este código descomprimirá cualquier archivo .zip en el directorio de documentos de su aplicación y obtendrá el archivo de los recursos de la aplicación.

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];

Es realmente difícil descomprimir cualquier archivo zip arbitrario. Es un formato de archivo complejo, y potencialmente hay muchas rutinas de compresión diferentes que podrían haberse utilizado internamente en el archivo. Info-ZIP tiene un código libremente licenciable para hacerlo ( http: // www .info-zip.org / UnZip.html ) que puede funcionar en el iPhone con algo de piratería, pero la API es francamente horrible: implica pasar argumentos de línea de comandos a un "principal" falso que simula la ejecución de UnZIP (para ser justos, eso se debe a que su código nunca fue diseñado para usarse así, en primer lugar, la funcionalidad de la biblioteca se atornilló después).

Si tiene algún control sobre el origen de los archivos que está intentando descomprimir, altamente le recomiendo usar otro sistema de compresión en lugar de ZIP. Su flexibilidad y ubicuidad lo hacen ideal para pasar archivos de archivos de persona a persona, pero es muy difícil de automatizar.

zlib no está diseñado para abrir archivos .zip, pero estás de suerte: el directorio contrib de zlib incluye minizip, que puede usar zlib para abrir archivos .zip.

Puede que no esté incluido en el SDK, pero probablemente pueda usar la versión incluida de zlib para usarlo. Obtenga una copia de la fuente zlib y busque en contrib / minizip.

No he usado el iPhone, pero es posible que desee consultar GZIP , que es un biblioteca zip de código abierto muy portátil disponible para muchas plataformas.

Tuve un poco de suerte probando esto en el simulador de 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]);       
}

Parece más fácil que jugar con zlib ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top