Подтвердить что ты не робот

Распаковка файлов

Я хочу отображать OpenOffice файлы,.odt и .odp на стороне клиента с помощью веб-браузера.

Эти файлы являются заархивированными файлами. Используя Ajax, я могу получить эти файлы с сервера, но это файлы с zip файлами. Мне нужно распаковать их, используя JavaScript, я пробовал использовать inflate.js, http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt, но безуспешно.

Как я могу это сделать?

4b9b3361

Ответ 1

Я написал unzipper в Javascript. Оно работает.

Он полагается на Энди Г.П. Na для чтения бинарных файлов и некоторые RFC1951 раздувают логику от notmasteryet. Я добавил класс ZipFile.

рабочий пример:
http://cheeso.members.winisp.net/Unzip-Example.htm (мертвая ссылка)

Источник:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (мертвая ссылка)

NB: ссылки мертвы; Скоро найду нового хозяина.

В качестве источника используется демонстрационная страница 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 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 файл. Там асинхронный обратный вызов для того, когда чтение завершается (как правило, происходит менее чем за секунду для разумных размеров zips) - в этой демонстрации обратный вызов сохраняется в локальной переменной doneReading, которая просто вызывает extractEntries, что просто слепо распаковывает все содержимое предоставленного zip файла. В реальном приложении вы, вероятно, выберете некоторые из извлекаемых записей (разрешите пользователю выбирать или выбирать одну или несколько записей программно и т.д.).

extractEntries fn выполняет итерацию по всем записям и вызывает на каждом из них extract(), передавая обратный вызов. Декомпрессия записи занимает время, возможно, 1 с или больше для каждой записи в zip файле, что означает, что асинхронность является подходящей. Обратный вызов extract просто добавляет извлеченный контент в аккордеон jQuery на странице. Если содержимое двоично, то оно форматируется как таковое (не показано).


Это работает, но я думаю, что утилита несколько ограничена.

С одной стороны: это очень медленно. Занимает ~ 4 секунды, чтобы разархивировать 140k файл AppNote.txt из PKWare. Такое же uncompress можно сделать менее чем за 0,5 с в .NET-программе. EDIT: Javascript ZipFile распаковывается значительно быстрее, чем это сейчас, в IE9 и в Chrome. Он по-прежнему медленнее, чем скомпилированная программа, но для обычного использования браузера он достаточно быстрый.

Для другого: он не выполняет потоковую передачу. Это в основном завалы во всем содержимом zipfile в память. В "реальной" среде программирования вы можете читать только метаданные zip файла (скажем, 64 байта на запись), а затем читать и распаковывать другие данные по желанию. Невозможно сделать IO, как в javascript, насколько я знаю, поэтому единственный вариант - прочитать весь zip в памяти и сделать произвольный доступ в нем. Это означает, что для больших zip файлов будут предъявляться необоснованные требования к системной памяти. Не так много для небольшого zip файла.

Кроме того: он не обрабатывает zip файл "общий регистр" - есть много опций zip, которые я не удосужился реализовать в unzipper - как шифрование ZIP, шифрование WinZip, zip64, UTF- 8 закодированных имен файлов, и т.д. ( EDIT - теперь он обрабатывает имена файлов с кодировкой UTF-8). Однако класс ZipFile обрабатывает основы. Некоторые из этих вещей не будут трудно реализовать. У меня класс шифрования AES в Javascript; которые могут быть интегрированы для поддержки шифрования. Поддержка Zip64, вероятно, будет бесполезной для большинства пользователей Javascript, поскольку она предназначена для поддержки > 4gb zipfiles - не нужно извлекать их в браузере.

Я также не тестировал случай распаковки двоичного содержимого. Прямо сейчас он распаковывает текст. Если у вас есть заархивированный двоичный файл, вам нужно будет отредактировать класс ZipFile для правильной обработки. Я не понял, как это сделать. Теперь он делает двоичные файлы.


EDIT. Я обновил библиотеку JS и демо-версию. Теперь он содержит двоичные файлы, в дополнение к тексту. Я сделал его более устойчивым и более общим - теперь вы можете указать кодировку, используемую при чтении текстовых файлов. Кроме того, демонстрационная версия расширена - она ​​показывает, помимо прочего, файл XLSX в браузере.

Итак, хотя я думаю, что он имеет ограниченную полезность и интерес, он работает. Я предполагаю, что это сработает в Node.js.

Ответ 2

Я использую zip.js, и это кажется весьма полезным. Это стоит посмотреть!

Отметьте Unzip demo, например.

Ответ 3

Я нашел jszip весьма полезным. Я использовал пока только для чтения, но у них есть возможности для создания и редактирования.

Код мудрый выглядит примерно так:

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

Одна вещь, которую я заметил, это то, что файл должен быть в двоичном потоковом формате (читается с использованием .readAsArrayBuffer из FileReader(), в противном случае я получал ошибки, говоря, что у меня может быть поврежденный zip файл

Ответ 4

Пример кода представлен на сайте автора. Вы можете использовать babelfish для перевода текстов (с японского на английский).

Насколько я понимаю японский, этот код задувания zip предназначен для декодирования ZIP-данных (потоков), а не ZIP-архива.

Ответ 6

Я написал "Бинарные инструменты для JavaScript", проект с открытым исходным кодом, который включает в себя возможность распаковывать, распаковывать и распаковывать: https://github.com/codedread/bitjs

Используется в моем читателе комиксов: https://github.com/codedread/kthoom (также с открытым исходным кодом).

НТН!