javascript - 解压缩文件

标签 javascript zip unzip

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

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

我怎样才能做到这一点?

最佳答案

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

它依赖于Andy G.P. Na's binary file readersome RFC1951 inflate logic from notmasteryet。我添加了ZipFile类。

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

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

注意:链接已死;我很快就会找到新主人。

源代码中包含一个ZipFile.htm演示页面,以及3个不同的脚本,一个用于zipfile类,一个用于inflate类,一个用于二进制文件读取器类。该演示还取决于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));
    }
}




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

extractEntries fn遍历所有条目,并在每个条目上调用extract(),并传递一个回调。对条目进行解压缩需要花费时间,对于zip文件中的每个条目而言,可能需要1秒或更长时间,这意味着异步是合适的。 extract回调只是将提取的内容添加到页面上的jQuery手风琴中。如果内容为二进制,则将其格式化(未显示)。



它可以工作,但是我认为该实用程序有些有限。

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

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

另外:它不处理“一般情况”的zip文件-我没有费心在解压缩中实现许多zip选项-例如ZIP加密,WinZip加密,zip64,UTF-8编码的文件名等等上。 (编辑-现在处理UTF-8编码的文件名)。但是,ZipFile类处理基础知识。其中一些事情将不难实现。我的Java语言中有an AES encryption class;可以集成以支持加密。对于大多数Javascript用户而言,支持Zip64可能会毫无用处,因为它旨在支持> 4gb zip文件-无需在浏览器中提取这些文件。

我也没有测试解压缩二进制内容的情况。现在,它会解压缩文本。如果您有一个压缩的二进制文件,则需要编辑ZipFile类以正确处理它。我没有弄清楚如何做到这一点。它现在也执行二进制文件。



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

因此,尽管我认为它的用途和兴趣有限,但它确实有效。我猜它可以在Node.js中工作。

关于javascript - 解压缩文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32907912/

相关文章:

javascript - 在没有第三方应用程序的情况下实现两要素身份验证

java - 如何调试库代码中出现的 NullPointerException?

c# - 如何将 2 个 zip 文件合并为 1 个?

javascript - 如何使用javascript在客户端系统中提取Zip文件

javascript - 如何在 Dreamweaver 中使用 JavaScript 创建点击计数器?

javascript - JavaScript中变量前的感叹号是什么意思

javascript - Font Awesome 图标下拉在移动设备上损坏

c# - 从内存中的 List<Byte[]> 创建 Zip 文件

vbscript - 如何在不实际提取文件的情况下使用 VBScript 读取 .zip 文件的内容?

java - 使用 Java 压缩和解压缩文件夹和文件