解压缩文件

use*_*260 70 javascript zip unzip

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

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

我怎样才能做到这一点?

Che*_*eso 61

我在Javascript中写了一个unzipper.有用.

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

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

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

NB:链接已经死了; 我很快就会找到一个新的主人.

包含在源是ZipFile.htm演示页,和3个不同的脚本,一个zip文件类,一个是充气类,以及一个用于二进制文件阅读器类.该演示还依赖于jQuery和jQuery UI.如果您只是下载js-zip.zip文件,那么所有必需的源代码都在那里.


以下是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));
    }
}
Run Code Online (Sandbox Code Playgroud)

演示工作在几个步骤:readFileFN通过点击触发,实例化一个对象使用ZipFile,内容的zip文件.有读完成时的异步回调(通常发生在合理规模的拉链不到一秒钟) -在这个演示回调在doneReading局部变量,它只是呼吁举行extractEntries,这只是盲目解压所提供的所有内容zip文件.在真实的应用程序中,您可能会选择一些要提取的条目(允许用户选择,或以编程方式选择一个或多个条目等).

extractEntriesFN遍历所有条目,并呼吁extract()各一个,通过一个回调.对于zipfile中的每个条目,条目的解压缩需要时间,可能是1或更多,这意味着异步是合适的.提取回调只是将提取的内容添加到页面上的jQuery手风琴中.如果内容是二进制的,则它被格式化(未示出).


它有效,但我认为效用有限.

一方面:这很慢.从PKWare解压缩140k AppNote.txt文件大约需要4秒钟.在.NET程序中,可以在小于.5秒内完成相同的解压缩. 编辑:在IE9和Chrome中,Javascript ZipFile的解压缩速度比现在快得多.它仍然比编译的程序慢,但它对于正常的浏览器使用来说是快速的.

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

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

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


编辑 - 我更新了JS解压缩库和演示.除了文本之外,它现在还会执行二进制文件.我已经使它更具弹性和更通用 - 您现在可以指定在读取文本文件时使用的编码.此外,该演示还展开了 - 它显示了在浏览器中解压缩XLSX文件等等.

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

  • Cheeso这很棒,你有更新的链接吗? (3认同)
  • 刚刚收到一个标志,声称链接已失效。您可以再次检查一下,并将代码放入您的 SO 答案中吗?您将获得 30,000 个字符。如果这还不够,请发布第二个答案。这些链接继续下去并没有任何好处。 (2认同)

Dan*_*HOP 26

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

例如,查看解压缩演示.


Alv*_*oFG 12

我发现jszip非常有用.到目前为止我只用于阅读,但他们也有创建/编辑功能.

代码明智它看起来像这样

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

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


MyS*_*ror 6

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

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