在 javascript 中使用 JSZIP 提取压缩文件
Extracting zipped files using JSZIP in javascript
在我的网页中,用户应该上传一个压缩文件。压缩文件中有 2 个文件:另一个 zip 文件和一个 txt 文件。在我的服务器上,收到 zip 后,我想解压缩 zip 文件以提取 zip 和 txt 文件,然后将这 2 个文件移动到预定义的文件夹中。我有一段提取 zip 文件的代码,但数据似乎不正确。首先,当只有 1 个 txt 文件时,它解压缩了一个 zip 和 2 个 txt 文件。它创建了一个额外的 'undefined' 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);
});
});
}
});
在他们的文档中进行了一些挖掘,但他们有 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);
});
});
});
}
});
这是我正在使用的工作版本:
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获得大部分你需要的信息,但是在一个地方很难获得,你必须四处看看。
这个答案是 cordova-plugin-file
具体的。
如 docs 中所述:
Directory entries have to be created successively. For example, the
call fs.root.getDirectory('dir1/dir2', {create:true}, successCallback,
errorCallback) will fail if dir1 did not exist.
我几乎可以肯定当前接受的答案不能保证文件 content/folders 总是以相同的顺序检索。这可能会导致 API 出现问题,例如 cordova-plugin-file
。特别是当您调用另一个异步函数在文件系统上异步创建目录时。
您可能想先过滤 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;
}
这是我在 Angular 10 中的策略,将单个文件写入具有自定义扩展名的 zip,然后读取同一个 zip 以检索 json。
将文件打包成zip(支持自定义文件结尾)
import { saveAs } from 'file-saver';
import * as JSZip from 'jszip';
export async function exportJson(
filename: string,
jsonToExport: string,
fileNameEnding = '.zip'
): Promise<string> {
const jsonFile = new Blob([jsonToExport], {
type: 'application/json',
});
if (!jsonFile) return Promise.reject('Error converting file to JSON');
const zipper = new JSZip();
zipper.file(`${filename}.json`, jsonFile);
const zippedFile = await zipper.generateAsync({ type: 'blob' });
const exportFilename = `${filename}${fileNameEnding}`;
saveAs(zippedFile, exportFilename);
return Promise.resolve(exportFilename);
}
从 zip 中读取文件内容
// file parameter retrieved from an input type=file
export async function readExportedJson(file: File): Promise<Blob> {
const zipper = new JSZip();
const unzippedFiles = await zipper.loadAsync(file);
return Promise.resolve(unzippedFiles).then(unzipped => {
if (!Object.keys(unzipped.files).length) {
return Promise.reject('No file was found');
}
return unzipped.files[Object.keys(unzipped.files)[0]];
}).then(unzippedFile => zipper.file(unzippedFile.name).async('string'));
}
在我的网页中,用户应该上传一个压缩文件。压缩文件中有 2 个文件:另一个 zip 文件和一个 txt 文件。在我的服务器上,收到 zip 后,我想解压缩 zip 文件以提取 zip 和 txt 文件,然后将这 2 个文件移动到预定义的文件夹中。我有一段提取 zip 文件的代码,但数据似乎不正确。首先,当只有 1 个 txt 文件时,它解压缩了一个 zip 和 2 个 txt 文件。它创建了一个额外的 'undefined' 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);
});
});
}
});
在他们的文档中进行了一些挖掘,但他们有 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);
});
});
});
}
});
这是我正在使用的工作版本:
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获得大部分你需要的信息,但是在一个地方很难获得,你必须四处看看。
这个答案是 cordova-plugin-file
具体的。
如 docs 中所述:
Directory entries have to be created successively. For example, the call fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback) will fail if dir1 did not exist.
我几乎可以肯定当前接受的答案不能保证文件 content/folders 总是以相同的顺序检索。这可能会导致 API 出现问题,例如 cordova-plugin-file
。特别是当您调用另一个异步函数在文件系统上异步创建目录时。
您可能想先过滤 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;
}
这是我在 Angular 10 中的策略,将单个文件写入具有自定义扩展名的 zip,然后读取同一个 zip 以检索 json。
将文件打包成zip(支持自定义文件结尾)
import { saveAs } from 'file-saver';
import * as JSZip from 'jszip';
export async function exportJson(
filename: string,
jsonToExport: string,
fileNameEnding = '.zip'
): Promise<string> {
const jsonFile = new Blob([jsonToExport], {
type: 'application/json',
});
if (!jsonFile) return Promise.reject('Error converting file to JSON');
const zipper = new JSZip();
zipper.file(`${filename}.json`, jsonFile);
const zippedFile = await zipper.generateAsync({ type: 'blob' });
const exportFilename = `${filename}${fileNameEnding}`;
saveAs(zippedFile, exportFilename);
return Promise.resolve(exportFilename);
}
从 zip 中读取文件内容
// file parameter retrieved from an input type=file
export async function readExportedJson(file: File): Promise<Blob> {
const zipper = new JSZip();
const unzippedFiles = await zipper.loadAsync(file);
return Promise.resolve(unzippedFiles).then(unzipped => {
if (!Object.keys(unzipped.files).length) {
return Promise.reject('No file was found');
}
return unzipped.files[Object.keys(unzipped.files)[0]];
}).then(unzippedFile => zipper.file(unzippedFile.name).async('string'));
}