Разархивировать zip без скачивания на диск.



  • Столкнулся с задачей, есть ссылка на файл - zip архив. Его нужно скачать, разархивировать и прочитать.
    Можно конечно скачать архив HTTP-клиент >> скачать на винт и использовать тот же 7-Zip, но это не интересно :D.

    Нашёл на npm интересную библиотеку adm-zip. И нагуглил код чтобы "загрузить zip файл из Интернета и разархивировать его в память без сохранения во временный файл." Для него ещё нужна библиотека request.

    var file_url = 'https://community.bablosoft.com/uploads/files/1522352901575-1.zip';
    
    var request = require('request');
    var fs = require('fs');
    var AdmZip = require('adm-zip');
    var http = require('http');
    var url = require('url');
    
    var options = {
        host: url.parse(file_url).host,
        port: 80,
        path: url.parse(file_url).pathname
    };
    
    http.get(options, function(res) {
        var data = [], dataLen = 0; 
    
        res.on('data', function(chunk) {
    
                data.push(chunk);
                dataLen += chunk.length;
    
            }).on('end', function() {
                var buf = new Buffer(dataLen);
    
                for (var i=0, len = data.length, pos = 0; i < len; i++) { 
                    data[i].copy(buf, pos); 
                    pos += data[i].length; 
                } 
    
                var zip = new AdmZip(buf);
                var zipEntries = zip.getEntries();
                console.log(zipEntries.length)
    
                for (var i = 0; i < zipEntries.length; i++)
                    console.log(zip.readAsText(zipEntries[i])); 
            });
    });
    

    Но безуспешно, в переменных пусто. Пойду мучить await.
    Может есть у кого опыт или готовое решение?



  • @fox Я тоже столкнулся с вопросом разархивировать zip архив с помощью bas для дальнейшей работы.
    Вам удалось решить этот вопрос?



  • @nesamit Разархивировать zip архив не сложно, я хотел именно без скачивания на диск, сделать всё в буфере.


  • Banned

    @fox ОЗУ не жалько? Блин заметил 21.3 что стал таким трудным( иа понимаю это все ради @senerg и других пользователей, Но как напрягает робить с модулями распозналки в нем. Нашел баг, не баг хз) Кароч если сравнивать и он знает одну одну переменную, а вторую нет или она указанна неверное (что чаще) он начинает и вылетает. Совсем наглухо закрывает открытый экземпляр баса. Остальное не трогает, но этот ажна через винду ломится закрывать и не спрашивает.
    Ну мож это у меня так. Я не в курсе.



  • @fox а как разархивировать через бас?



  • @nesamit

    @fox а как разархивировать через бас?

    Через ноду, например через вот этот модуль https://www.npmjs.com/package/node-zip



  • @Fox said in Разархивировать zip без скачивания на диск.:

    var request = require('request');

    не могу установить этот модуль, в поиске его даже не находит http://prntscr.com/ra9d1y



  • @graf said in Разархивировать zip без скачивания на диск.:

    @Fox said in Разархивировать zip без скачивания на диск.:

    var request = require('request');

    не могу установить этот модуль, в поиске его даже не находит http://prntscr.com/ra9d1y

    Он уже установлен





  • @graf, чтобы он работал нужно просто добавить var request = require('request'); перед его вызовом.



  • @GhostZ said in Разархивировать zip без скачивания на диск.:

    нужно просто добавить var request = require('request');

    http://prntscr.com/ra9htp всё установлено. в папке с модулями он присутствует. может как-то можно удалить всё, чтобы после перезапуска заново скачалось?

    UPD: Очистил всё по пути BrowserAutomationStudio\apps\22.5.0\embedded
    не вылечилось



  • @graf, удалите все из папки embedded



  • Проверил у товарища, всё тоже самое. что я делаю не так?) или это массовая проблема?)



  • @graf said in Разархивировать zip без скачивания на диск.:

    Проверил у товарища, всё тоже самое. что я делаю не так?) или это массовая проблема?)

    await(new Promise((resolve, reject) => {
        const request = require('../../node_modules/npm/node_modules/request');
        request("https://www.google.com", function (err, res, body) {
            console.log("err: " + err)
            console.log("res: " + res)
            console.log("body: " + body)
            resolve()
        })
    
    }));
    

    Тестовый скрипт



  • ты должен получить zip archive как Stream
    и потом этот Stream выдает события например файлы итд

    открываешь соединение и как только получил что нужно закрываешь Stream
    например .destroy
    я сделал утилиту которая читает вложенные файлы из zip gz архивов,
    это для еластика и там огромные файлы по 100+gb есть
    поэтому можно прочитать первые 10к строкиз gz файла который находится
    в зип архиве который находится в другом зип архиве итд.

    или прочитать рекурсивно первые n cтрочек всех текстовых файлов из всех архивов из директории рекурсивно без разархивации.

    пример(stream может быть локальный файл или удаленный)

    const streamToString = async (
    stream: Stream.Readable,
    opts: {
    maxLines?: number
    },
    ): Promise<string> => {
    const { maxLines } = opts
    let nLine = 0
    const lines: string[] = []

    const writable = es.mapSync((line: string) => {
    if (nLine >= 0 && nLine % 1e3 === 0) logdebug('nLine: %s', nLine)
    if (line) {
    lines.push(line)
    nLine++
    if (maxLines && nLine >= maxLines) {
    // logdebug('streamToString::complete')
    writable.end()
    }
    }
    })

    await new Promise((resolve, reject) => {
    stream
    .pipe(es.split())
    .pipe(writable)
    .on('error', err => {
    logdebug('error:streamToString %O', err)
    reject('Error during untar for : ' + err)
    })
    .on('end', async () => {
    // logdebug('stream:end')
    resolve()
    })
    })
    return lines.join('\n')
    }





  • @Fox Ваш вариант работает, благодарю. получается путь к модулю нужно указывать "чуточку точнее")



  • @Fox said in Разархивировать zip без скачивания на диск.:

    Тестовый скрипт

    Не совсем понял, что именно делает тестовый скрипт?
    Можно для нубов пояснить? :)



  • @AngelOfAncient said in Разархивировать zip без скачивания на диск.:

    @Fox said in Разархивировать zip без скачивания на диск.:

    Тестовый скрипт

    Не совсем понял, что именно делает тестовый скрипт?
    Можно для нубов пояснить? :)

    Я не помню уже, но судя по прикреплённому коду это просто проверка модуля "request". Код отправляет get-запрос на страницу https://www.google.com и выводит в консоль результаты



  • @Fox said in Разархивировать zip без скачивания на диск.:

    Через ноду, например через вот этот модуль https://www.npmjs.com/package/node-zip

    Скачал модуль. Копирую из мануала:

    var zip = new require('node-zip')(data, {base64: false, checkCRC32: true});
    console.log(zip.files['test.file']); // Hello there
    

    В моём случае это:

    var zip = new require('node-zip')("ZIP/1.zip", {base64: false, checkCRC32: true});
    console.log(zip.files['"ZIP/1.zip"']); 
    

    Выдаёт в логе "Error: Can't find end of central directory : is this a zip file ? If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html".

    Смысл ошибки - он не распознаёт файл архива как архив?
    И даёт ссылку уже на другой (?) пакет JSZip, где ещё всё более загадочно.

    1. Если считать файл в переменную FILE_CONTENT обычным способом, то получаем ошибку:
      Error: End of data reached (data length = 27585, asked index = 28669). Corrupted zip ?
      При коде:
    var zip = new require('node-zip')([[FILE_CONTENT]], {base64: false, checkCRC32: true});
    
    1. Если считать файл в переменную FILE_CONTENT как Base64, то первая команда вроде бы работает:
    var zip = new require('node-zip')([[FILE_CONTENT]], {base64: true, checkCRC32: true});
    console.log(zip.files['test.file']); // Hello there
    

    Некоторое время висит-работает, потом выдаёт в лог Undefined.
    В этом случае не понятно, куда он распаковывает эти файлы, если распаковывает.
    ...
    В сухом остатке, если есть под рукой тестовый скрипт разархивации Zip через Ноду (Не на лету, а обычным способом со скачиванием) - думаю, многим будет актуально.


Log in to reply