【问题标题】:Zipping and uploading files using PhoneGap and JSZip使用 PhoneGap 和 JSZip 压缩和上传文件
【发布时间】:2015-02-13 13:35:59
【问题描述】:

我的代码可以读取本地文件夹,然后压缩相关文件并将它们上传到服务器:

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 函数返回 Promise,然后使用 Promise.all(...).then() 模式,但有时我仍然得到一个空白文件。所以要么我的实现不正确,要么 zip.generate() 也异步运行(或两者兼而有之)。

如何确保 zip 文件在尝试上传之前已完全写入存储?

【问题讨论】:

    标签: cordova promise filereader jszip ramda.js


    【解决方案1】:

    FileReader API 是异步的:当您创建编写器时,阅读器可能仍在等待(并且 zip 文件仍然为空)。 Promise 在这里是正确的模式,只需确保在将文件添加到 zip 后解决 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 才会解析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 1970-01-01
      相关资源
      最近更新 更多