使用JSZip库提取ZIP文件

3
我正在使用HTML/JS在Windows 8上工作。我试图提取一个使用FilePicker选择的Zip文件。
为了提取Zip文件,我正在使用这个页面中的函数:http://blog.appliedis.com/2013/09/18/zipping-and-unzipping-files-in-a-winjs-application/
在此链接中有一个用于提取Zip文件的函数unzipAsync
function unzipAsync(filePath, replaceIfExists) {

    var fileCollisionOption = replaceIfExists ?
        storage.CreationCollisionOption.replaceExisting :
        storage.CreationCollisionOption.failIfExists;

    return storage.StorageFile
        .getFileFromPathAsync(filePath)
        .then(getFileAsUint8Array)
        .then(function (zipFileContents) {
            //Create the zip data in memory
            var zip = new JSZip(zipFileContents);

            //Extract files
            var promises = [];
            var lf = storage.ApplicationData.current.localFolder;
            _.each(zip.files, function (zippedFile) {

                //Create new file
                promises.push(lf
                    .createFileAsync(zippedFile.name, fileCollisionOption)
                    .then(function (localStorageFile) {
                        //Copy the zipped file's contents into the local storage file
                        var fileContents = zip.file(zippedFile.name).asUint8Array();
                        return storage.FileIO
                            .writeBytesAsync(localStorageFile, fileContents);
                    })
                );
            });

            return WinJS.Promise.join(promises);
        });
}

在此之前,我将JSZIP库添加到项目文件夹中。
请帮忙,我该如何将该库集成到我的项目中。这是我的项目链接
编辑:
function getFileAsUint8Array(file) {
    return storage.FileIO.readBufferAsync(file)
        .then(function (buffer) {
            //Read the file into a byte array
            var fileContents = new Uint8Array(buffer.length);
            var dataReader = storage.Streams.DataReader.fromBuffer(buffer);
            dataReader.readBytes(fileContents);
            dataReader.close();

            return fileContents;
        });
}

现在它可以正常工作,但是它并没有像提取我的文件那样做任何事情。

注意:

- 如果有人知道任何比这更好的方法或者我可以用来提取WinJS文件的其他库,请建议我。

2个回答

3

我猜想你没有创建一个getFileAsUint8Array函数(或者至少,在上面的代码中没有展示出来)。虽然我从XHL调用中获取zip文件,但是我在做类似的事情。一旦我有了zip文件和我想要放置zip文件的文件夹,我就会像下面的代码一样做。

然而请注意,我不得不修改这个代码,因为我还做了其他一些事情,所以我没有完全按照它进行测试(显然它不能在上述代码中工作)。

这是(大部分)完整的代码:

WinJS.xhr({ "url": zipUrl, "responseType": "arraybuffer" })
    .done(
        function (e) {
            if (!e.getResponseHeader("content-type") === "application/zip") {
                console.error("Remote file was not sent with correct Content-Type: expected 'application/zip', but received '" + e.getResponseHeader("content-type") + "'");
            }

            unzipAndStore(new JSZip(e.response), someLocalFolder);
        },
        function() { /* handle ajax errors */ }
    );

/**
 * @param {JSZip} jszipobj The JSZip object
 * @param {StorageFolder} localFolder The folder to unzip into
 * @return {Promise}
 */
var unzipAndStore = function (jszipobj, localFolder) {
    var promises = [];

    Object.keys(jszipobj.files).forEach(function (key) {
        var fileName;

        // ignore folder entries, they're handled as needed below
        if (/\/$/.test(key)) { return; }

        fileName = jszipobj.files[key].name.match(/[^\/]+\.[^\.\/]+$/);
        if (!fileName) {
            console.error("Unable to process zip entry without proper filename: ", jszipobj.files[key].name);
            return;
        }
        fileName = fileName[0];

        promises.push(
            getFolderFromPathRecursive(jszipobj.files[key].name, localFolder)
                .then(
                    function (subFolder) {
                        console.log("creating file in folder: ", fileName, subFolder.name);

                        return subFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.replaceExisting)
                    }
                )
                .then(
                    function (localStorageFile) {
                        return Windows.Storage.FileIO
                            .writeBytesAsync(localStorageFile, jszipobj.file(jszipobj.files[key].name).asUint8Array());
                    }
                )
        );

    });

    return WinJS.Promise.join(promises);
};

/**
 * Promise completes with the lowest level folder in the given path, 
 * creating subfolders along the way
 * @param {String} path The path to the lowest subfolder you want a reference to
 * @param {StorageFolder} rootFolder The folder to begin at for this iteration
 * @return {Promise}
 */
var getFolderFromPathRecursive = function (path, rootFolder) {
    var normalizedPath = path.replace(/\/?[^\/]+\.[^\.\/]+$/, ""),  // remove a possible filename from the end of the path
        folders = normalizedPath.split(/\//), // get an array of the folders in the path
        subFolderName = folders.shift(); // remove the first folder in the path as the new one to create

    return new WinJS.Promise(function (complete, error) {
        if (!subFolderName || !subFolderName.length) {
            complete(rootFolder);
            return;
        }

        rootFolder
            .createFolderAsync(subFolderName, Windows.Storage.CreationCollisionOption.openIfExists)
                .then(
                    function (folder) {
                        return getFolderFromPathRecursive(folders.join("/"), folder);
                    },
                    error
                )
                .then(
                    function(folder) {
                        complete(folder);
                        return;
                    },
                    error
                )
    });
};

很遗憾,我没能理解你的代码。你能添加更多描述或任何来源链接将会有帮助。是的,我缺少 'getFileAsUint8Array' 函数。在添加该函数后,我并没有得出结论。谢谢。 - Kumar
嗨,我编辑了我的问题。我忘记在帖子中更改描述。我只是遵循这个链接[http://blog.appliedis.com/2013/09/18/zipping-and-unzipping-files-in-a-winjs-application/]。你可以尝试使用我添加的示例项目。我无法更改我的项目中的编辑。现在我不在工作中。谢谢。 - Kumar
我猜你无法尝试我的项目,但你能否至少告诉我如何使用你的代码来提取文件呢?现在我已经使用“Filepicker”选择了文件详细信息。但是之后我没有任何线索来集成你的代码。因为我没有找到有关使用“WinJS”提取文件的相关帮助。提前感谢你的帮助。 - Kumar
抱歉,我只是没有时间处理这个。如果我找到了30分钟的空闲时间,我会尝试在这个周末组织一些东西。 - Jordan Kasper
无需翻译。感谢您的尝试和时间 :) - Kumar
显示剩余2条评论

0

我在我的JavaScript项目中添加了C# Windows运行时,使用解压示例进行了操作。

这是我的帖子


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接