Javascript 解压文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2095697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:45:01  来源:igfitidea点击:

Unzipping files

javascriptzipunzip

提问by user69260

I want to display OpenOfficefiles, .odt and .odp at client side using a web browser.

我想使用 Web 浏览器在客户端显示OpenOffice文件、.odt 和 .odp。

These files are zipped files. Using Ajax, I can get these files from server but these are zipped files. I have to unzip them using JavaScript, I have tried using inflate.js, http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt, but without success.

这些文件是压缩文件。使用 Ajax,我可以从服务器获取这些文件,但这些文件是压缩文件。我必须使用JavaScript解压缩它们,我尝试使用 inflate.js,http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt ,但没有成功。

How can I do this?

我怎样才能做到这一点?

采纳答案by Cheeso

I wrote an unzipper in Javascript. It works.

我用Javascript编写了一个解压缩器。有用。

It relies on Andy G.P. Na's binary file readerand some RFC1951 inflate logic from notmasteryet. I added the ZipFile class.

它依赖于Andy GP Na 的二进制文件阅读器一些来自 notmasteryet 的 RFC1951 膨胀逻辑。我添加了 ZipFile 类。

working example:
http://cheeso.members.winisp.net/Unzip-Example.htm(dead link)

工作示例:
http: //cheeso.members.winisp.net/Unzip-Example.htm(死链接)

The source:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip(dead link)

来源:
http: //cheeso.members.winisp.net/srcview.aspx?dir=js-unzip(死链接)

NB: the links are dead; I'll find a new host soon.

注意:链接已失效;我很快就会找到一个新的主人。

Included in the source is a ZipFile.htm demonstration page, and 3 distinct scripts, one for the zipfile class, one for the inflate class, and one for a binary file reader class. The demo also depends on jQuery and jQuery UI. If you just download the js-zip.zip file, all of the necessary source is there.

源代码中包含一个 ZipFile.htm 演示页面和 3 个不同的脚本,一个用于 zipfile 类,一个用于 inflate 类,另一个用于二进制文件读取器类。该演示还依赖于 jQuery 和 jQuery UI。如果您只是下载 js-zip.zip 文件,则所有必需的源都在那里。



Here's what the application code looks like in Javascript:

下面是应用程序代码在 Javascript 中的样子:

// In my demo, this gets attached to a click event.
// it instantiates a ZipFile, and provides a callback that is
// invoked when the zip is read.  This can take a few seconds on a
// large zip file, so it's asynchronous. 
var readFile = function(){
    $("#status").html("<br/>");
    var url= $("#urlToLoad").val();
    var doneReading = function(zip){
        extractEntries(zip);
    };

    var zipFile = new ZipFile(url, doneReading);
};


// this function extracts the entries from an instantiated zip
function extractEntries(zip){
    $('#report').accordion('destroy');

    // clear
    $("#report").html('');

    var extractCb = function(id) {
        // this callback is invoked with the entry name, and entry text
        // in my demo, the text is just injected into an accordion panel.
        return (function(entryName, entryText){
            var content = entryText.replace(new RegExp( "\n", "g" ), "<br/>");
            $("#"+id).html(content);
            $("#status").append("extract cb, entry(" + entryName + ")  id(" + id + ")<br/>");
            $('#report').accordion('destroy');
            $('#report').accordion({collapsible:true, active:false});
        });
    }

    // for each entry in the zip, extract it. 
    for (var i=0; i<zip.entries.length;  i++) {
        var entry = zip.entries[i];

        var entryInfo = "<h4><a>" + entry.name + "</a></h4>\n<div>";

        // contrive an id for the entry, make it unique
        var randomId = "id-"+ Math.floor((Math.random() * 1000000000));

        entryInfo += "<span class='inputDiv'><h4>Content:</h4><span id='" + randomId +
            "'></span></span></div>\n";

        // insert the info for one entry as the last child within the report div
        $("#report").append(entryInfo);

        // extract asynchronously
        entry.extract(extractCb(randomId));
    }
}


The demo works in a couple of steps: The readFilefn is triggered by a click, and instantiates a ZipFile object, which reads the zip file. There's an asynchronous callback for when the read completes (usually happens in less than a second for reasonably sized zips) - in this demo the callback is held in the doneReading local variable, which simply calls extractEntries, which just blindly unzips all the content of the provided zip file. In a real app you would probably choose some of the entries to extract (allow the user to select, or choose one or more entries programmatically, etc).

该演示分为几个步骤:readFilefn 由单击触发,并实例化一个 ZipFile 对象,该对象读取 zip 文件。读取完成时有一个异步回调(对于合理大小的 zip,通常会在不到一秒的时间内发生) - 在这个演示中,回调保存在 doneReading 局部变量中,它只是调用extractEntries,它只是盲目地解压缩所提供的所有内容压缩文件。在真实的应用程序中,您可能会选择一些要提取的条目(允许用户选择,或以编程方式选择一个或多个条目等)。

The extractEntriesfn iterates over all entries, and calls extract()on each one, passing a callback. Decompression of an entry takes time, maybe 1s or more for each entry in the zipfile, which means asynchrony is appropriate. The extract callback simply adds the extracted content to an jQuery accordion on the page. If the content is binary, then it gets formatted as such (not shown).

extractEntries在所有条目FN迭代,并呼吁extract()各一个,通过一个回调。一个条目的解压需要时间,对于 zipfile 中的每个条目可能需要 1 秒或更长时间,这意味着异步是合适的。提取回调只是将提取的内容添加到页面上的 jQuery 手风琴中。如果内容是二进制的,那么它会被格式化(未显示)。



It works, but I think that the utility is somewhat limited.

它有效,但我认为该实用程序有些有限。

For one thing: It's very slow. Takes ~4 seconds to unzip the 140k AppNote.txt file from PKWare. The same uncompress can be done in less than .5s in a .NET program.EDIT: The Javascript ZipFile unpacks considerably faster than this now, in IE9 and in Chrome. It is still slower than a compiled program, but it is plenty fast for normal browser usage.

一方面:它非常慢。从 PKWare 解压 140k AppNote.txt 文件需要大约 4 秒。在 .NET 程序中,同样的解压缩可以在不到 0.5 秒的时间内完成。编辑:在 IE9 和 Chrome 中,Javascript ZipFile 的解包速度比现在快得多。它仍然比编译的程序慢,但对于正常的浏览器使用来说已经足够快了。

For another: it does not do streaming. It basically slurps in the entire contents of the zipfile into memory. In a "real" programming environment you could read in only the metadata of a zip file (say, 64 bytes per entry) and then read and decompress the other data as desired. There's no way to do IO like that in javascript, as far as I know, therefore the only option is to read the entire zip into memory and do random access in it. This means it will place unreasonable demands on system memory for large zip files. Not so much a problem for a smaller zip file.

另一个:它不做流媒体。它基本上将 zipfile 的全部内容放入内存中。在“真实”的编程环境中,您只能读取 zip 文件的元数据(例如,每个条目 64 字节),然后根据需要读取和解压缩其他数据。据我所知,在 javascript 中没有办法像那样做 IO,因此唯一的选择是将整个 zip 读入内存并在其中进行随机访问。这意味着它会对大型 zip 文件的系统内存提出不合理的要求。对于较小的 zip 文件来说问题不大。

Also: It doesn't handle the "general case" zip file - there are lots of zip options that I didn't bother to implement in the unzipper - like ZIP encryption, WinZip encryption, zip64, UTF-8 encoded filenames,and so on. (EDIT- it handles UTF-8 encoded filenames now). The ZipFile class handles the basics, though. Some of these things would not be hard to implement. I have an AES encryption classin Javascript; that could be integrated to support encryption. Supporting Zip64 would probably useless for most users of Javascript, as it is intended to support >4gb zipfiles - don't need to extract those in a browser.

另外:它不处理“一般情况”的 zip 文件——有很多 zip 选项我没有费心在解压器中实现——比如 ZIP 加密、WinZip 加密、zip64、UTF-8 编码的文件名等等在。(编辑- 它现在处理 UTF-8 编码的文件名)。不过, ZipFile 类处理基础知识。其中一些事情并不难实施。我在 Javascript 中有一个 AES 加密类;可以集成以支持加密。对于大多数 Javascript 用户来说,支持 Zip64 可能没用,因为它旨在支持 >4gb 的 zipfiles - 不需要在浏览器中提取它们。

I also did not test the case for unzipping binary content. Right now it unzips text. If you have a zipped binary file, you'd need to edit the ZipFile class to handle it properly. I didn't figure out how to do that cleanly. It does binary files now, too.

我也没有测试解压缩二进制内容的情况。现在它解压缩文本。如果你有一个压缩的二进制文件,你需要编辑 ZipFile 类来正确处理它。我不知道如何干净地做到这一点。它现在也处理二进制文件。



EDIT- I updated the JS unzip library and demo. It now does binary files, in addition to text. I've made it more resilient and more general - you can now specify the encoding to use when reading text files. Also the demo is expanded - it shows unzipping an XLSX file in the browser, among other things.

编辑- 我更新了 JS 解压缩库和演示。除了文本之外,它现在还处理二进制文件。我使它更具弹性和更通用 - 您现在可以指定在读取文本文件时使用的编码。演示也得到了扩展 - 它显示了在浏览器中解压缩 XLSX 文件等。

So, while I think it is of limited utility and interest, it works. I guess it would work in Node.js.

所以,虽然我认为它的实用性和兴趣有限,但它确实有效。我想它可以在 Node.js 中工作。

回答by Dani bISHOP

I'm using zip.jsand it seems to be quite useful. It's worth a look!

我正在使用zip.js,它似乎非常有用。值得一看!

Check the Unzip demo, for example.

例如,检查解压缩演示

回答by AlvaroFG

I found jszipquite useful. I've used so far only for reading, but they have create/edit capabilities as well.

我发现jszip非常有用。到目前为止,我仅用于阅读,但它们也具有创建/编辑功能。

Code wise it looks something like this

代码明智它看起来像这样

var new_zip = new JSZip();
new_zip.load(file);
new_zip.files["doc.xml"].asText() // this give you the text in the file

One thing I noticed is that it seems the file has to be in binary stream format (read using the .readAsArrayBuffer of FileReader(), otherwise I was getting errors saying I might have a corrupt zip file

我注意到的一件事是,文件似乎必须是二进制流格式(使用 FileReader() 的 .readAsArrayBuffer 读取,否则我会收到错误消息,说我可能有一个损坏的 zip 文件

Edit: Note from the 2.x to 3.0.0 upgrade guide:

编辑:从 2.x 到 3.0.0 升级指南的注意事项

The load() method and the constructor with data (new JSZip(data)) have been replaced by loadAsync().

load() 方法和带有数据的构造函数(new JSZip(data))已被 loadAsync() 替换。

Thanks user2677034

感谢用户2677034

回答by MySqlError

If you need to support other formats as well or just need good performance, you can use this WebAssembly library

如果您还需要支持其他格式或只需要良好的性能,您可以使用这个WebAssembly 库

it's promised based, it uses WebWorkers for threading and API is actually simple ES module

它是基于承诺的,它使用 WebWorkers 进行线程处理,API 实际上是简单的 ES 模块

回答by codedread

I wrote "Binary Tools for JavaScript", an open source project that includes the ability to unzip, unrar and untar: https://github.com/codedread/bitjs

我写了“JavaScript 二进制工具”,这是一个开源项目,包括解压、解压和解压功能:https: //github.com/codedread/bitjs

Used in my comic book reader: https://github.com/codedread/kthoom(also open source).

在我的漫画书阅读器中使用:https: //github.com/codedread/ktoom(也是开源的)。

HTH!

哼!

回答by TheBrain

I wrote a class for that too. http://blog.another-d-mention.ro/programming/read-load-files-from-zip-in-javascript/You can load basic assets such as javascript/css/images directly from the zip using class methods. Hope it helps

我也为此写了一个类。 http://blog.another-d-mention.ro/programming/read-load-files-from-zip-in-javascript/您可以使用类方法直接从 zip 加载基本资产,例如 javascript/css/images。希望能帮助到你

回答by OcuS

Code example is given on the author site's. You can use babelfishto translate the texts (Japanese to English).

代码示例在作者站点的. 您可以使用babelfish来翻译文本(日语到英语)。

As far as I understand Japanese, this zip inflate code is meant to decode ZIP data (streams) not ZIP archive.

据我了解日语,这个 zip inflate 代码是为了解码 ZIP 数据(流)而不是 ZIP 存档。