使用 PhoneGap 和 JSZip 压缩和上传文件
Zipping and uploading files using PhoneGap and JSZip
我有读取本地文件夹的代码,然后压缩相关文件并将它们上传到服务器:
var dirEntry = fileSystem.createReader();
dirEntry.readEntries(
function (entries) {
if (entries.length === 0)
return;
var options = new FileUploadOptions();
/* Details omitted */
var zip = new JSZip();
// Map function from Ramda library
R.map(function (entry) {
var fileName = entry.name;
// Check that this is a file, and it's not a zip file.
if (entry.isFile && (fileName.indexOf(".zip", fileName.length - 4) == -1)) {
return entry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
// Add the file to the Zip
zip.file(fileName, evt.target.result);
};
reader.readAsArrayBuffer(file);
}, function (error) { // ignore });
}
return null;
}, entries);
fileSystem.getFile(options.fileName, { create: true, exclusive: false },
function (fileEntry) {
fileEntry.createWriter(function (writer) {
// Generate the binary Zip file
var content = zip.generate({ type: "blob", compression: "DEFLATE" });
// Upload the file after it's persisted to storage
writer.onwriteend = function (evt) {
var ft = new FileTransfer();
ft.upload(fileEntry.nativeURL,
UPLOAD_SERVER_URL,
function (data) { // Ignore },
function (error) { // Ignore },
options)
};
// Persist the zip file to storage
writer.write(content);
}, function (error) {
// Ignore
});
}, function (error) {
// Ignore
});
}
, errorFunction);
问题是有时会上传一个空文件,这种情况永远不会发生。因此,可能是同步问题导致文件在 Zip 文件创建并写入存储之前上传。我不确定问题出在哪里。我试过从 Map 函数返回 Promises,然后使用 Promise.all(...).then() 模式,但有时我仍然得到一个空白文件。所以要么我的实现不正确,要么 zip.generate() 也异步运行(或两者)。
如何确保 zip 文件在尝试上传之前已完全写入存储?
FileReader API 是异步的:当您创建编写器时,reader 可能仍在等待(并且 zip 文件仍然是空的)。
Promises 在这里是正确的模式,只要确保在将文件添加到 zip
:
后 resolve the promise
var promises = R.map(function (entry) {
// ...
var deferred = Q.defer(); // <= create here
reader.onloadend = function (evt) {
zip.file(fileName, evt.target.result);
deferred.resolve(text); // <= resolve here
// call deferred.reject when you encounter an error
}
reader.readAsArrayBuffer(file);
return deferred.promise;
}, entries);
// then, Promise.all(...).then()
这样,只有在内容添加到 zip
后,promise 才会解析。
我有读取本地文件夹的代码,然后压缩相关文件并将它们上传到服务器:
var dirEntry = fileSystem.createReader();
dirEntry.readEntries(
function (entries) {
if (entries.length === 0)
return;
var options = new FileUploadOptions();
/* Details omitted */
var zip = new JSZip();
// Map function from Ramda library
R.map(function (entry) {
var fileName = entry.name;
// Check that this is a file, and it's not a zip file.
if (entry.isFile && (fileName.indexOf(".zip", fileName.length - 4) == -1)) {
return entry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
// Add the file to the Zip
zip.file(fileName, evt.target.result);
};
reader.readAsArrayBuffer(file);
}, function (error) { // ignore });
}
return null;
}, entries);
fileSystem.getFile(options.fileName, { create: true, exclusive: false },
function (fileEntry) {
fileEntry.createWriter(function (writer) {
// Generate the binary Zip file
var content = zip.generate({ type: "blob", compression: "DEFLATE" });
// Upload the file after it's persisted to storage
writer.onwriteend = function (evt) {
var ft = new FileTransfer();
ft.upload(fileEntry.nativeURL,
UPLOAD_SERVER_URL,
function (data) { // Ignore },
function (error) { // Ignore },
options)
};
// Persist the zip file to storage
writer.write(content);
}, function (error) {
// Ignore
});
}, function (error) {
// Ignore
});
}
, errorFunction);
问题是有时会上传一个空文件,这种情况永远不会发生。因此,可能是同步问题导致文件在 Zip 文件创建并写入存储之前上传。我不确定问题出在哪里。我试过从 Map 函数返回 Promises,然后使用 Promise.all(...).then() 模式,但有时我仍然得到一个空白文件。所以要么我的实现不正确,要么 zip.generate() 也异步运行(或两者)。
如何确保 zip 文件在尝试上传之前已完全写入存储?
FileReader API 是异步的:当您创建编写器时,reader 可能仍在等待(并且 zip 文件仍然是空的)。
Promises 在这里是正确的模式,只要确保在将文件添加到 zip
:
var promises = R.map(function (entry) {
// ...
var deferred = Q.defer(); // <= create here
reader.onloadend = function (evt) {
zip.file(fileName, evt.target.result);
deferred.resolve(text); // <= resolve here
// call deferred.reject when you encounter an error
}
reader.readAsArrayBuffer(file);
return deferred.promise;
}, entries);
// then, Promise.all(...).then()
这样,只有在内容添加到 zip
后,promise 才会解析。