解压文件

发布于 2024-08-18 13:51:24 字数 477 浏览 12 评论 0原文

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

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

我该怎么做?

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

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.

How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

嗼ふ静 2024-08-25 13:51:24

我用 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,通常在不到一秒的时间内发生) - 在此演示中,回调保存在 didReading 局部变量中,该变量仅调用 extractEntries,其中
只是盲目地解压缩所提供的 zip 文件的所有内容。在真实的应用程序中,您可能会选择一些条目来提取(允许用户选择,或以编程方式选择一个或多个条目等)。

extractEntries fn 迭代所有条目,并对每个条目调用 extract(),并传递回调。条目的解压需要时间,zip 文件中的每个条目可能需要 1 秒或更多,这意味着异步是合适的。 extract 回调只是将提取的内容添加到页面上的 jQuery 手风琴中。如果内容是二进制的,那么它会被格式化(未显示)。


它确实有效,但我认为实用性有些有限。

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

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

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

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


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

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

I wrote an unzipper in Javascript. It works.

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

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

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

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.


Here's what the application code looks like in 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 readFile fn 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).

The extractEntries fn 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).


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.

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.

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 class in 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.

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.


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.

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

网名女生简单气质 2024-08-25 13:51:24

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

例如,检查解压缩演示

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

Check the Unzip demo, for example.

忆梦 2024-08-25 13:51:24

我发现 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()方法和带数据的构造函数(new JSZip(data))有
已被 loadAsync() 取代。

感谢用户2677034

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

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

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

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

Thanks user2677034

独木成林 2024-08-25 13:51:24

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

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

如何使用

npm i libarchive.js 安装并将其用作 ES 模块。

该库由两部分组成:ES 模块和 webworker 包,ES 模块部分是与库对话的接口,像任何其他模块一样使用它。 webworker 捆绑包位于 libarchive.js/dist 文件夹中,因此您需要确保它在您的公共文件夹中可用,因为如果您使用捆绑器(它已经全部捆绑在一起),则它不会被捆绑,并指定正确的路径Archive.init() 方法。

import {Archive} from 'libarchive.js/main.js';

Archive.init({
    workerUrl: 'libarchive.js/dist/worker-bundle.js'
});

document.getElementById('file').addEventListener('change', async (e) => {
    const file = e.currentTarget.files[0];

    const archive = await Archive.open(file);
    let obj = await archive.extractFiles();
    
    console.log(obj);
});

// outputs
{
    ".gitignore": {File},
    "addon": {
        "addon.py": {File},
        "addon.xml": {File}
    },
    "README.md": {File}
}

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

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

How to use

Install with npm i libarchive.js and use it as a ES module.

The library consists of two parts: ES module and webworker bundle, ES module part is your interface to talk to library, use it like any other module. The webworker bundle lives in the libarchive.js/dist folder so you need to make sure that it is available in your public folder since it will not get bundled if you're using bundler (it's all bundled up already) and specify correct path to Archive.init() method.

import {Archive} from 'libarchive.js/main.js';

Archive.init({
    workerUrl: 'libarchive.js/dist/worker-bundle.js'
});

document.getElementById('file').addEventListener('change', async (e) => {
    const file = e.currentTarget.files[0];

    const archive = await Archive.open(file);
    let obj = await archive.extractFiles();
    
    console.log(obj);
});

// outputs
{
    ".gitignore": {File},
    "addon": {
        "addon.py": {File},
        "addon.xml": {File}
    },
    "README.md": {File}
}
梨涡少年 2024-08-25 13:51:24

我写了“Binary Tools for JavaScript”,这是一个开源项目,包含解压缩、解压缩和解压的功能:https: //github.com/codedread/bitjs

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

哈!

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

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

HTH!

许你一世情深 2024-08-25 13:51:24

如果有人从远程服务器托管的 zip 文件中读取图像或其他二进制文件,您可以使用以下代码片段来下载并使用 jszip 库。

// this function just get the public url of zip file.
let url = await getStorageUrl(path) 
console.log('public url is', url)
//get the zip file to client
axios.get(url, { responseType: 'arraybuffer' }).then((res) => {
  console.log('zip download status ', res.status)
//load contents into jszip and create an object
  jszip.loadAsync(new Blob([res.data], { type: 'application/zip' })).then((zip) => {
    const zipObj = zip
    $.each(zip.files, function (index, zipEntry) {
    console.log('filename', zipEntry.name)
    })
  })

现在使用 zipObj 您可以访问文件并为其创建 src url。

var fname = 'myImage.jpg'
zipObj.file(fname).async('blob').then((blob) => {
var blobUrl = URL.createObjectURL(blob)

If anyone's reading images or other binary files from a zip file hosted at a remote server, you can use following snippet to download and create zip object using the jszip library.

// this function just get the public url of zip file.
let url = await getStorageUrl(path) 
console.log('public url is', url)
//get the zip file to client
axios.get(url, { responseType: 'arraybuffer' }).then((res) => {
  console.log('zip download status ', res.status)
//load contents into jszip and create an object
  jszip.loadAsync(new Blob([res.data], { type: 'application/zip' })).then((zip) => {
    const zipObj = zip
    $.each(zip.files, function (index, zipEntry) {
    console.log('filename', zipEntry.name)
    })
  })

Now using the zipObj you can access the files and create a src url for it.

var fname = 'myImage.jpg'
zipObj.file(fname).async('blob').then((blob) => {
var blobUrl = URL.createObjectURL(blob)
清醇 2024-08-25 13:51:24

2023 答案

自 Chrome 中 ~2020 年和 Safari 中 ~2023 年起,您可以使用标准压缩流 API。
https://developer.mozilla.org/en-US/docs/ Web/API/Compression_Streams_API

例如,这里是如何解压使用 Java 的“DeflaterOutputStream”制作的数据:

let DecompressionStream = globalThis["DecompressionStream"];

export async function zipInflate(zip: Uint8Array): Promise<Uint8Array> {
    let ds = new DecompressionStream("deflate");
    let blob = new Blob([zip]);
    const decompressedStream = blob.stream().pipeThrough(ds);
    let blob2 = await new Response(decompressedStream).blob();
    let ab = await blob2.arrayBuffer();
    let arB = new Uint8Array(ab);
    return arB;
}

上面的来源是 TypeScript。如果您需要 JavaScript,请删除冒号后面的类型说明符。

2023 Answer

Since ~2020 in Chrome and ~2023 in Safari you can use the standard Compression Streams API.
https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API

For example, here is how to unzip data made with Java's "DeflaterOutputStream":

let DecompressionStream = globalThis["DecompressionStream"];

export async function zipInflate(zip: Uint8Array): Promise<Uint8Array> {
    let ds = new DecompressionStream("deflate");
    let blob = new Blob([zip]);
    const decompressedStream = blob.stream().pipeThrough(ds);
    let blob2 = await new Response(decompressedStream).blob();
    let ab = await blob2.arrayBuffer();
    let arB = new Uint8Array(ab);
    return arB;
}

The above source is TypeScript. If you need JavaScript please just remove the type specifiers after the colons.

独行侠 2024-08-25 13:51:24

受到 这篇文章,我创建了一个基本的零依赖 TypeScript 解决方案,该解决方案依赖于新的 压缩流 API

async function extractZipFile(zip: Uint8Array, fileName: string): Promise<Uint8Array | undefined> {
    const dataView = new DataView(zip.buffer);
    let index = 0;
    while (true) { // eslint-disable-line no-constant-condition
        const signature = dataView.getUint32(index, true);
        if (signature === 0x04034b50) { // local file
            const fileNameLength = dataView.getUint16(index + 26, true);
            const thisFileName = [...zip.slice(index + 30, index + 30 + fileNameLength)].map((b) => String.fromCharCode(b)).join("");
            const startsAt = index + 30 + fileNameLength + dataView.getUint16(index + 28, true);
            const compressedSize = dataView.getUint32(index + 18, true);
            if (thisFileName === fileName) {
                const compressionMethod = dataView.getUint16(index + 8, true);
                const buffer = zip.slice(startsAt, startsAt + compressedSize);
                if (compressionMethod === 0x00){
                    return buffer;
                } else if (compressionMethod === 0x08) {
                    return new Uint8Array(await new Response(new Blob([buffer]).stream().pipeThrough(new DecompressionStream("deflate-raw"))).arrayBuffer());
                } else {
                    throw new Error(`Unknown compression method 0x${compressionMethod.toString(16)}`);
                }
            } else {
                index = startsAt + compressedSize;
            }
        } else if (signature === 0x02014b50) { // central directory
            index += 46 + dataView.getUint16(index + 28, true) + dataView.getUint16(index + 30, true) + dataView.getUint16(index + 32, true);
        } else if (signature === 0x06054b50) { // end of central directory
            break;
        } else {
            throw new Error(`Unrecognized signature 0x${signature.toString(16)}`);
        }
    }
}

它采用二进制 ZIP 文件并从中提取单个文件,通过文件名进行标识。文件名应包含其目录路径,例如 test/file.txt。该函数返回文件的解压缩内容,如果 ZIP 文件不包含给定名称的文件,则返回未定义的内容。如果 ZIP 文件包含多个具有该名称的文件,则返回第一个文件。

但是,ZIP 文件可以以多种形式出现,特别是,上面的代码在以下情况下会遇到麻烦:

  • ZIP 文件内的文件可以使用多种压缩方法。上面的代码只支持两种最常见的,8(压缩)和0(不压缩)。
  • 文件名可以用不同的方式编码。上面假设 ISO-8859-1,并且当使用不同的编码时将无法按预期工作。
  • ZIP64 是 ZIP 的变体,支持更大的文件。上面的代码将无法处理它。
  • 许多 ZIP 文件缺少压缩大小元数据,因为它们的内容是动态压缩的,而是在每个文件之后的数据签名中以及位于以下位置的中央目录中列出压缩大小:结束。上面的代码将无法处理此类文件。正确的方法是从末尾解析 ZIP 文件,猜测中央目录从哪里开始,然后从中提取压缩大小。

正如您所看到的,只要您知道文件的开始和结束位置,并且文件不使用压缩或使用压缩流 API 支持的压缩,从 ZIP 文件中提取文件就非常容易。但有很多情况并非如此。仅当您确定提供的文件不会落入上面列出的任何边缘情况时,才使用上述代码。否则,请使用许多其他答案中推荐的库。

Inspired by the code in this article, I have created a basic zero-dependencies TypeScript solution that relies on the new Compression Streams API:

async function extractZipFile(zip: Uint8Array, fileName: string): Promise<Uint8Array | undefined> {
    const dataView = new DataView(zip.buffer);
    let index = 0;
    while (true) { // eslint-disable-line no-constant-condition
        const signature = dataView.getUint32(index, true);
        if (signature === 0x04034b50) { // local file
            const fileNameLength = dataView.getUint16(index + 26, true);
            const thisFileName = [...zip.slice(index + 30, index + 30 + fileNameLength)].map((b) => String.fromCharCode(b)).join("");
            const startsAt = index + 30 + fileNameLength + dataView.getUint16(index + 28, true);
            const compressedSize = dataView.getUint32(index + 18, true);
            if (thisFileName === fileName) {
                const compressionMethod = dataView.getUint16(index + 8, true);
                const buffer = zip.slice(startsAt, startsAt + compressedSize);
                if (compressionMethod === 0x00){
                    return buffer;
                } else if (compressionMethod === 0x08) {
                    return new Uint8Array(await new Response(new Blob([buffer]).stream().pipeThrough(new DecompressionStream("deflate-raw"))).arrayBuffer());
                } else {
                    throw new Error(`Unknown compression method 0x${compressionMethod.toString(16)}`);
                }
            } else {
                index = startsAt + compressedSize;
            }
        } else if (signature === 0x02014b50) { // central directory
            index += 46 + dataView.getUint16(index + 28, true) + dataView.getUint16(index + 30, true) + dataView.getUint16(index + 32, true);
        } else if (signature === 0x06054b50) { // end of central directory
            break;
        } else {
            throw new Error(`Unrecognized signature 0x${signature.toString(16)}`);
        }
    }
}

It takes a binary ZIP file and extracts a single file from it, identified by its file name. The file name should include its directory path, for example test/file.txt. The function returns the decompressed content of the file, or undefined if the ZIP file does not contain a file with the given name. If the ZIP file contains multiple files with that name, the first one is returned.

However, ZIP files can appear in a variety of shapes, and in particular, the above code will have trouble in the following scenarios:

  • Files inside a ZIP file can use a large variety of compression methods. The above code only supports the two most common ones, 8 (deflate) and 0 (no compression).
  • File names can be encoded in different ways. The above assumes ISO-8859-1 and will not work as expected when a different encoding is used.
  • ZIP64 is a variation of ZIP that supports larger files. The above code will fail to handle it.
  • Many ZIP files lack the compressed size metadata because their content was compressed on the fly, and instead list the compressed size in a data signature after each file and in the central directory at the end. The above code will fail to handle such files. The right way would be to parse the ZIP file from the end, guess where the central directory starts, and extract the compressed sizes from that.

As you can see, extracting a file from a ZIP file is very easy as long as you know the start and end position of the file and it is using no compression or one supported by the Compression Streams API. But there are lots of scenarios where this is not the case. Use the above code only if you are certain that the files provided will not fall into any of the edge cases listed above. Otherwise, use a library as recommended in many of the other answers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文