Question

Vraiment coincé dans la tentative d'écrire du code pour décompresser un fichier ou un répertoire sur l'iPhone.

Vous trouverez ci-dessous un exemple de code que j'utilise pour essayer de décompresser un fichier texte simple.

Le fichier est décompressé mais corrompu.

(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);  
}
Était-ce utile?

La solution

contient "sample.zip " vraiment été créé avec gZip? L’extension .zip est généralement utilisée pour les archives créées par WinZip. Ceux-ci peuvent également être décompressés en utilisant zLib, mais vous devrez analyser l'en-tête et utiliser d'autres routines.

Pour vérifier, jetez un coup d’œil aux deux premiers octets du fichier. Si c'est "PK", c'est WinZip, si c'est 0x1F8B, c'est gZip.

Étant donné que cela est spécifique à l'iPhone, consultez cette Discussion sur le forum du kit de développement logiciel (SDK) pour iPhone miniZip est mentionné . Il semble que cela puisse gérer les fichiers WinZip.

Mais s'il s'agit vraiment d'un fichier WinZip, vous devez consulter le Spécification WinZip. et essayez d'analyser le fichier vous-même. Il doit en principe analyser certaines valeurs d’en-tête, rechercher la position du flux compressé et utiliser les routines zLib pour le décompresser.

Autres conseils

Je voulais une solution simple mais je n’en ai pas trouvé une qui me plaise ici. J’ai donc modifié une bibliothèque pour faire ce que je voulais. Vous pouvez trouver SSZipArchive . (Il peut également créer des fichiers zip au passage.)

Utilisation:

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

Ce code a bien fonctionné pour moi pour gzip:

la base de données a été préparée comme ceci:     gzip foo.db

la clé faisait une boucle sur gzread (). L'exemple ci-dessus ne lit que les premiers octets 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");

Incidemment, je peux décompresser 33 Mo en 130 Mo en 77 secondes ou environ 1,7 Mo non compressé / seconde.

Ce code va décompresser n'importe quel fichier .zip dans le répertoire du document de votre application et le récupérer dans les ressources de l'application.

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

Il est très difficile de décompresser un fichier zip arbitraire. C'est un format de fichier complexe, et il existe potentiellement de nombreuses routines de compression différentes qui auraient pu être utilisées en interne dans le fichier. Info-ZIP dispose d'un code librement licencable pour le faire ( http: // www .info-zip.org / UnZip.html ) qui peut fonctionner avec un peu de piratage sur l’iPhone, mais l’API est franchement horrible. Elle implique de passer des arguments en ligne de commande à un faux "principal" simulant le fonctionnement de UnZIP (pour être juste c'est parce que leur code n'a jamais été conçu pour être utilisé de cette façon, les fonctionnalités de la bibliothèque ont été ajoutées par la suite).

Si vous avez le moindre contrôle sur la provenance des fichiers que vous essayez de décompresser, je vivement vous recommandons d'utiliser un autre système de compression au lieu de ZIP. Sa flexibilité et son omniprésence lui permettent de transmettre des archives de fichiers de personne à personne, mais il est très difficile à automatiser.

zlib n'est pas destiné à ouvrir des fichiers .zip, mais vous avez de la chance: le répertoire contrib de zlib inclut minizip, qui permet d'utiliser zlib pour ouvrir des fichiers .zip.

Il n’est peut-être pas fourni avec le SDK, mais vous pouvez probablement utiliser la version fournie de zlib. Prenez une copie de la source zlib et cherchez dans contrib / minizip.

Je n'ai pas utilisé l'iPhone, mais vous voudrez peut-être consulter GZIP , qui est un bibliothèque zip open source très portable disponible pour de nombreuses plateformes.

J'ai eu de la chance de le tester sur le simulateur 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]);       
}

Cela semble plus facile que de jouer avec zlib ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top