在javascript

时间:2016-09-05 01:44:35

标签: javascript unzip jszip

在我的网页中,用户应该上传压缩文件。在压缩文件中有2个文件:另一个zip文件和一个txt文件。在我的服务器上,收到zip后,我想解压缩zip文件以解压缩& txt文件,然后将这2个文件移动到预定义的文件夹。我有一段代码提取zip文件,但数据看起来不正确。首先,当只有1个txt文件时,它解压缩了一个zip和2个txt文件。它创造了一个额外的未定义的' txt文件。另外,在我的txt文件中,它不是原始数据,而是替换为以下文本:' [undefined] [undefined]'。
谁可以帮我这个事?以下是我的代码:

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

3 个答案:

答案 0 :(得分:13)

这是我正在使用的工作版本:

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      
    })
  })
})

你可以从http://stuk.github.io/jszip/documentation/examples.html获得所需的大部分信息,但是在一个地方有点困难,你必须环顾四周。

答案 1 :(得分:6)

他们的文档需要花费一些时间,但是他们有an example来展示如何从ZIP中读取文件内容。

您将获得描述 ZIP内容但不是实际内容的对象。这是一个经过调整的版本:

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

答案 2 :(得分:0)

此答案是cordova-plugin-file特定的。

docs中所述:

  

必须连续创建目录条目。例如,   呼叫fs.root.getDirectory('dir1 / dir2',{create:true},successCallback,   如果dir1不存在,则errorCallback将会失败。

我几乎可以肯定,当前接受的答案不能保证始终按相同顺序检索文件内容/文件夹。这可能会导致诸如cordova-plugin-file之类的API出现问题。尤其是当您调用另一个异步函数以在文件系统上异步创建目录时。

您可能要先过滤zip存档的目录并以同步方式创建它们,然后再继续按已回答的方式提取其他文件:

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