web-dev-qa-db-fra.com

Extraire des fichiers compressés à l'aide de JSZIP en javascript

Dans ma page Web, un utilisateur est censé télécharger un fichier compressé. Le fichier compressé contient 2 fichiers: un autre fichier Zip et un fichier txt. Sur mon serveur, après avoir reçu le Zip, je veux décompresser le fichier Zip pour extraire le fichier Zip & txt, puis déplacer ces 2 fichiers dans un dossier prédéfini. J'ai un morceau de code qui extrait le fichier Zip, mais les données ne semblent pas correctes. Premièrement, il a décompressé un fichier Zip et 2 txt alors qu'il ne devrait y avoir qu'un seul fichier txt. Il a créé un fichier txt "non défini" supplémentaire. De plus, dans mon fichier txt, au lieu des données d'origine, il a été remplacé par le texte suivant: '[undefined] [undefined]'.
Quelqu'un peut-il m'aider à ce sujet? Voici mon code:

var JSZip = require('JSZip');

fs.readFile( filePath, function(err, data){
  if (!err){
    var Zip = new JSZip();
    JSZip.loadAsync(data).then(function(Zip){
      object.keys(Zip.files).forEach(function(filename){
        var content = Zip.files[filename];
        var dest = path + filename;
        fs.writeFileSync(dest, content);
      });
    });
  }
});
8
Cherple

Il a fallu un peu de fouille dans leur documentation mais ils ont n exemple qui montre comment lire le contenu du fichier à partir d'un Zip.

Vous obtenez l'objet qui décrit le contenu Zip mais pas le contenu réel. Voici une version ajustée:

var JSZip = require('JSZip');

fs.readFile(filePath, function(err, data) {
    if (!err) {
        var Zip = new JSZip();
        Zip.loadAsync(data).then(function(contents) {
            Object.keys(contents.files).forEach(function(filename) {
                Zip.file(filename).async('nodebuffer').then(function(content) {
                    var dest = path + filename;
                    fs.writeFileSync(dest, content);
                });
            });
        });
    }
});
8
geekonaut

Ceci est une version de travail que j'utilise:

var jsZip = require('jszip')
jsZip.loadAsync(file).then(function (Zip) {
  Object.keys(Zip.files).forEach(function (filename) {
    Zip.files[filename].async('string').then(function (fileData) {
      console.log(fileData) // These are your file contents      
    })
  })
})

Vous pouvez obtenir la plupart des informations dont vous avez besoin sur http://stuk.github.io/jszip/documentation/examples.html mais c'est un peu difficile de se trouver au même endroit, vous devez regarder autour de vous un peu.

16
webnoob

Cette réponse est cordova-plugin-file spécifique.

Comme indiqué dans le docs :

Les entrées du répertoire doivent être créées successivement. Par exemple, l'appel fs.root.getDirectory ('dir1/dir2', {create: true}, successCallback, errorCallback) échouera si dir1 n'existait pas.

Je suis presque certain que la réponse actuellement acceptée ne peut garantir que le contenu des fichiers/dossiers est toujours récupéré dans le même ordre. Cela pourrait entraîner des problèmes avec une API telle que cordova-plugin-file. Surtout lorsque vous appelez une autre fonction asynchrone pour créer de manière asynchrone le répertoire sur le système de fichiers.

Vous pouvez d'abord filtrer les répertoires de votre archive Zip et les créer de manière synchronisée avant de continuer à extraire d'autres fichiers comme déjà répondu:

const directoryNames = Object.keys(Zip.files).filter(name => Zip.files[name].dir);
for (const directoryName of directoryNames) {
    await this.createDirectory(directoryName, dirEntry);
}
// ...

private createDirectory = (dirName: string, dirEntry: DirectoryEntry) => {
    const promise = new Promise<DirectoryEntry>(resolve, reject) => {
        dirEntry.getDirectory(dirName, { create: true }, dirEntry => {
            resolve(dirEntry);
        }, fileError => reject(fileError));
    });
    return promise;
}
0
Yannic Hamann