解压缩文件


79

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

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

我怎样才能做到这一点?


7
“没有成功”请更具体,向我们展示一些代码,向我们展示一些错误...我们在这里为您提供帮助,而不是猜测。
OcuS 2010年

基本上,我只是称呼充气功能-data = zip_inflate(src); 但是我认为这是针对单个文件的。如果一个zip文件在目录结构中包含多个文件,那么“数据”的内容将是什么。我不知道如何使用这个库。
user69260 2010年

@Eimantas是什么意思?+或-
user69260

4
@techfandu:(1)单击您的名字。(2)单击您之前提出的问题。(3)接受对您最有帮助的答案。(4)重复直到所有问题得到可接受的答案。
戴夫·贾维斯

你的工作成功了吗?我必须在学校的一个项目上做同样的事情(在网络浏览器中播放odp)..如果您能给我一些指导,那就太糟糕了。
Alexx 2012年

Answers:


61

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

它依赖于Andy GP Na的二进制文件读取器以及notmasteryet的一些RFC1951膨胀逻辑。我添加了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,只是盲目地解压缩所提供内容的所有内容。压缩文件。在真实的应用程序中,您可能会选择一些要提取的条目(允许用户选择,或者以编程方式选择一个或多个条目等)。

extractEntries在所有条目FN迭代,并呼吁extract()各一个,通过一个回调。对条目进行解压缩需要花费时间,对于zip文件中的每个条目而言,可能需要1秒或更长时间,这意味着异步是合适的。提取回调仅将提取的内容添加到页面上的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类处理基础知识。其中一些事情将不难实现。我在Javascript中有一个AES加密类;可以集成以支持加密。对于大多数Javascript用户而言,支持Zip64可能无用,因为它旨在支持> 4gb的zip文件-无需在浏览器中提取这些文件。

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


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

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


这看起来不错,但我收到以下错误消息:该zipfile使用UTF8,ZipFile.js不支持。您可以推荐任何快速的解决方法吗?
朱利奥·普里斯科

@Giulio-好的,我修改了ZipFile类以支持对UTF8编码的文件名进行解码。它应该现在就可以工作。
Cheeso 2011年

太棒了!可以将KMZ(二进制)和KML(XML)支持添加到JSIO.guessFileType吗?
布伦丹·伯德

1
我有一个在线演示的旧版本,但我是来这里寻求更新的。如果您有时间,@ Cheeso将对更新的链接感兴趣。
geocodezip

1
@DannyBeckett-好的,谢谢您的提醒和建议。我会尽快将演示放在某个地方。
Cheeso

26

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

例如,查看Unzip演示


我使用的zip.js与您使用的zip.js相同,但是在safari中我未定义filereader。pls帮助我使用safari。
user969275 2013年

我没有使用Safari的经验。您应该询问zip.js开发人员。项目页面底部有一个电子邮件地址:gildas-lormeau.github.com/zip.js。也许这是一个错误,所以他们会感谢您的通知。
Dani bISHOP 2013年

感谢您的答复,我已经发表了一个问题。
user969275 2013年

我有一些JSON文件,其中包含以zip格式进行base64编码的JSON字符串。我需要那个内部JSON对象。Java的InflatorInputStream可以在服务器上解压缩它,因此它实际上是zip格式。但是,当我使用BlobReader将已解码的base64数据从atob()传递到zip.js时,出现“读取zip文件时出错”。错误。从视觉上看,atob()的输出是二进制的,因此BlobReader看起来是正确的,无论如何都尝试了TextReader,它给出了“无法识别文件格式”。有任何想法吗?
enigment

使用pako 在一行代码中解决了我的问题pako.inflate(binaryData, { to: 'string' })
谜题

17

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

明智的代码看起来像这样

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

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

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

load()方法和带有数据的构造函数(新的JSZip(data))已由loadAsync()取代。

谢谢user2677034


1
这对我有帮助。谢谢。:)
deekshith

1
JSZip 3.0中已删除此方法,请查看升级指南。
user2677034

1
谢谢男人,它是一个了不起的lib,因为它非常易于使用(与之前的答案相比)!
Maxim Georgievskiy

5

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

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




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.