Я написал распаковщик на Javascript. Оно работает.
Он полагается на программу чтения бинарных файлов Andy GP Na и некоторую логику расширения RFC1951 от notmasteret. . Я добавил класс 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:
var readFile = function(){
$("#status").html("<br/>");
var url= $("#urlToLoad").val();
var doneReading = function(zip){
extractEntries(zip);
};
var zipFile = new ZipFile(url, doneReading);
};
function extractEntries(zip){
$('#report').accordion('destroy');
$("#report").html('');
var extractCb = function(id) {
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 (var i=0; i<zip.entries.length; i++) {
var entry = zip.entries[i];
var entryInfo = "<h4><a>" + entry.name + "</a></h4>\n<div>";
var randomId = "id-"+ Math.floor((Math.random() * 1000000000));
entryInfo += "<span class='inputDiv'><h4>Content:</h4><span id='" + randomId +
"'></span></span></div>\n";
$("#report").append(entryInfo);
entry.extract(extractCb(randomId));
}
}
Демонстрация readFile
состоит из нескольких этапов: fn запускается щелчком мыши и создает экземпляр объекта ZipFile, который считывает zip-файл. Существует асинхронный обратный вызов, когда чтение завершается (обычно происходит менее чем за секунду для zip-файлов разумного размера) - в этой демонстрации обратный вызов хранится в локальной переменной doneReading, которая просто вызываетextractEntries
, которая просто слепо распаковывает все содержимое предоставленного zip-файл. В реальном приложении вы, вероятно, выберете некоторые записи для извлечения (разрешите пользователю выбрать или выбрать одну или несколько записей программно и т. Д.).
extractEntries
П перебирает все записи и вызовыextract()
каждую, передавая обратный вызов. Распаковка записи занимает время, может быть, 1 с или более для каждой записи в zip-файле, что означает, что асинхронность подходит. Обратный вызов extract просто добавляет извлеченный контент в аккордеон jQuery на странице. Если контент является двоичным, он форматируется как таковой (не показан).
Работает, но мне кажется, что полезность несколько ограничена.
Во-первых: это очень медленно. Распаковка 140 КБ файла AppNote.txt из PKWare занимает ~ 4 секунды. То же самое распаковывание может быть выполнено менее чем за 0,5 с в программе .NET. РЕДАКТИРОВАТЬ : Javascript ZipFile распаковывается значительно быстрее, чем сейчас, в IE9 и Chrome. Он по-прежнему медленнее, чем скомпилированная программа, но достаточно быстр для обычного использования браузера.
Для другого: он не выполняет потоковую передачу. По сути, он забирает все содержимое zip-файла в память. В «реальной» среде программирования вы можете читать только метаданные zip-файла (скажем, 64 байта на запись), а затем читать и распаковывать другие данные по желанию. Насколько я знаю, в javascript нет способа сделать такой ввод-вывод в javascript, поэтому единственный вариант - прочитать весь zip-архив в память и выполнить произвольный доступ к нему. Это означает, что для больших zip-файлов он будет предъявлять необоснованные требования к системной памяти. Не такая уж большая проблема для zip-файла меньшего размера.
Также: он не обрабатывает zip-файл «общего случая» - есть множество опций zip, которые я не потрудился реализовать в распаковщике - например, шифрование ZIP, шифрование WinZip, zip64, имена файлов в кодировке UTF-8 и т. Д. на. ( EDIT - теперь он обрабатывает имена файлов в кодировке UTF-8). Однако класс ZipFile обрабатывает основы. Некоторые из этих вещей было бы несложно реализовать. У меня есть класс шифрования AES в Javascript; которые можно интегрировать для поддержки шифрования. Поддержка Zip64, вероятно, бесполезна для большинства пользователей Javascript, поскольку он предназначен для поддержки zip-файлов размером более 4 ГБ - не нужно извлекать их в браузере.
Я также не тестировал случай распаковки двоичного содержимого. Прямо сейчас распаковывает текст. Если у вас есть заархивированный двоичный файл, вам нужно отредактировать класс ZipFile, чтобы он правильно обрабатывался. Я не понял, как это сделать чисто. Теперь он делает и двоичные файлы.
РЕДАКТИРОВАТЬ - Я обновил библиотеку распаковки JS и демонстрацию. Теперь он делает двоичные файлы в дополнение к тексту. Я сделал его более гибким и общим - теперь вы можете указать кодировку, которая будет использоваться при чтении текстовых файлов. Также расширена демонстрация - в ней, помимо прочего, показано распаковывание файла XLSX в браузере.
Так что, хотя я думаю, что это имеет ограниченную полезность и интерес, оно работает. Думаю, это сработает в Node.js.