Pergunta

Realmente preso em tentar escrever código para descompactar um arquivo ou diretório no iPhone.

Abaixo está um código de exemplo que estou usando para tentar descompactar um arquivo de texto simples.

Ele descompacta o arquivo, mas o seu corrupto.

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

Solução

Tem "sample.zip" realmente foi criado com gzip? A extensão .zip geralmente é usado para arquivos criados pelo WinZip. Aqueles também pode ser descompactado usando zlib, mas você teria que analisar o cabeçalho e usar outras rotinas.

Para verificar, ter um olhar para os dois primeiros bytes do arquivo. Se for 'PK', é WinZip, se é 0x1F8B, é gzip.

Porque este é o iPhone específico, ter um olhar para este iPhone SDK fórum de discussão onde miniZip é mencionada . Parece que este pode manipular arquivos WinZip.

Mas se é realmente um arquivo WinZip, você deve ter um olhar para o WinZip especificação e tentar analisar o arquivo de si mesmo. Basicamente, deve ser analisar alguns valores de cabeçalho, buscando a posição de fluxo comprimido e utilizando rotinas ZLib para descompactá-lo.

Outras dicas

Eu queria uma solução fácil e não encontrou um que eu gostei aqui, então eu modifiquei uma biblioteca para fazer o que eu queria. Você pode encontrar SSZipArchive útil. (Ele também pode criar arquivos zip pelo caminho.)

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 funcionou bem para mim para gzip:

o banco de dados foi preparado como este: gzip foo.db

a chave foi looping sobre o gzread (). O exemplo acima só lê a primeira parte bytes.

#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");

Aliás, posso descompactar 33MB para 130MB em 77 segundos ou cerca de 1,7 MB descompactado / segundo.

Este código será descompactar qualquer arquivo .zip em seu diretório documento aplicativo e arquivo começa a partir de recursos de aplicativos.

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

É muito difícil para descompactar qualquer arquivo zip arbitrária. É um formato de arquivo complexo, e há potencialmente muitos rotinas de compressão diferentes que poderiam ter sido usados ??internamente para o arquivo. Info-ZIP tem algum código livremente licencable para fazê-lo ( http: // www .info-zip.org / UnZip.html ) que pode ser feito para funcionar no iPhone com algum hacking, mas a API é francamente horrível - que envolve a passagem de argumentos de linha de comando para um falso 'main' que simula a corrida de descompactar (para ser justo isso porque seu código nunca foi projetado para ser usado como este, em primeiro lugar, a funcionalidade de biblioteca foi acrescentada depois).

Se você tem nenhum controle sobre onde os arquivos que você está tentando unzip estão vindo, eu altamente recomendo usar outro sistema de compressão em vez de ZIP. É de flexibilidade e onipresença torná-lo grande para passar arquivos de arquivos em torno de pessoa-a-pessoa, mas é muito difícil de automatizar.

zlib não se destina a arquivos .zip abertos, mas você está na sorte:. Diretório contrib da zlib inclui minizip, que é capaz de usar zlib para arquivos .zip abertas

Pode não ser empacotado no SDK, mas provavelmente você pode usar a versão de uso zlib-lo. Pegue uma cópia da fonte zlib e olhar em contrib / minizip.

Eu não usei o iPhone, mas você pode querer olhar em GZIP , que é um muito portátil open source zip disponível biblioteca para várias plataformas.

Eu tive um pouco de sorte testar isso no simulador do 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 mais fácil do que mexendo com zlib ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top