Я написав розпаковку в Javascript. Це працює.
Він покладається на зчитувач двійкових файлів Andy GP 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, один для класу надування та інший для класу зчитування двійкових файлів. Демо-версія також залежить від 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
Fn перебирає всі записи, і виклики extract()
на кожному з них, проходячи зворотний виклик. Декомпресія запису вимагає часу, може бути 1s або більше для кожного запису в zip-файлі, що означає, що асинхронність є доречною. Витяг зворотного виклику просто додає витягнутий вміст до акордеону jQuery на сторінці. Якщо вміст є двійковим, то він відформатовується як такий (не показано).
Це працює, але я думаю, що корисність дещо обмежена.
Одне: це дуже повільно. Розпакування файлу 140k AppNote.txt із PKWare займає ~ 4 секунди. Те саме розпакування можна зробити менш ніж за .5 с у програмі .NET. EDIT : Javascript ZipFile розпаковується значно швидше, ніж зараз, в IE9 та Chrome. Це все ще повільніше, ніж скомпільована програма, але вона досить швидка для звичайного використання браузера.
Для іншого: він не робить потокового передавання. По суті, це весь вміст zip-файлу в пам'ять. У "реальному" середовищі програмування ви можете читати лише метадані ZIP-файлу (скажімо, 64 байти на запис), а потім читати та розпаковувати інші дані за бажанням. Наскільки мені відомо, неможливо зробити подібне введення-виведення в javascript, тому єдиний варіант - прочитати весь zip-файл у пам’яті та зробити в ньому довільний доступ. Це означає, що це спричинить необґрунтовані вимоги до системної пам'яті для великих ZIP-файлів. Не стільки проблема для меншого zip-файлу.
Також: він не обробляє zip-файл "загального випадку" - існує безліч варіантів zip, які я не потрудився застосувати в розпаковці - наприклад, шифрування ZIP, шифрування WinZip, zip64, кодовані назви файлів UTF-8 тощо. на. ( EDIT - тепер обробляє кодовані імена файлів UTF-8). Однак клас ZipFile обробляє основи. Деякі з цих речей не складно реалізувати. У мене є клас шифрування AES у Javascript; які можуть бути інтегровані для підтримки шифрування. Підтримка Zip64, мабуть, була б марною для більшості користувачів Javascript, оскільки вона призначена для підтримки> 4gb zip-файлів - не потрібно витягувати їх у браузері.
Я також не перевіряв справу на розпакування двійкового вмісту. Зараз він розпаковує текст. Якщо у вас є заархівований двійковий файл, вам потрібно буде відредагувати клас ZipFile, щоб правильно його обробляти. Я не зрозумів, як це робити чисто. Зараз він також робить двійкові файли.
РЕДАКТУВАТИ - Я оновив бібліотеку та демонстраційну версію JS. Тепер він робить бінарні файли, крім тексту. Я зробив його більш еластичним та загальним - тепер ви можете вказати кодування, яке використовуватиметься при читанні текстових файлів. Також демонстрація розширена - серед іншого вона показує розпакування файлу XLSX у браузері.
Отже, хоча я думаю, що це обмежено корисно та цікаво, це працює. Я думаю, це працювало б у Node.js.