2016-08-29 5 views
1

Я ищу, используя JSZip, создаю zip-файл в файле из разных файлов вниз. Вот псевдо-код для того, что я пытаюсь сделать:JSZip в koa.js с потоковым вводом/выводом

function* handler() { 
    const ids = this.request.body.ids; 

    const zip = new JSZip(); 
    for (let i = 0; i < ids; i++) { 
     const r = yield request.get('/some/remote/service/' + ids[i]); 
     zip.file(ids[i], r.body); 
    } 
    this.body = zip.nodeStream(): 
} 

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

Я понимаю, что я мог бы оптимизировать время загрузки, делая что-то вроде:

const allFiles = yield ids.map((id) => request.get('/some/remote/service/' + id)); 

for (let i = 0; i < ids.length; i++) zip.file(ids[i], allFiles[i]); 

Но главным образом я надеюсь, что способ только держать один файл в памяти в то время, и поток результат через почтовый индекс обратно клиент. Возможно ли это с JSZip?

+0

Вы пытаетесь передать файлы в файл .zip, загруженный с клиентской стороны? – guest271314

+0

его немного сложнее, чем то, что я здесь представлял, но в основном на стороне сервера могут быть N файлов за определенным идентификатором, и клиент должен получить один ZIP-файл, содержащий все файлы. В хранилище данных на бэкэнд они не предварительно застегнуты, поэтому я буду делать это на лету. – Kevin

+0

, чтобы ответить на ваш вопрос; да, клиент дает идентификатор и ожидает, что ZIP-файл будет возвращен. – Kevin

ответ

0

Я надеюсь на способ хранить только один файл в памяти и передавать результат через zip обратно клиенту. Возможно ли это с JSZip?

Не без недостатков. JSZip не принимает (yet) генератор или функцию в качестве содержимого файла. Он ожидает полного содержимого файла, его обещания или потока. Это означает, что вы не можете (пока) вызвать вызовы API в последний момент, когда контент действительно необходим.

Когда вы добавляете поток (с zip.file("filename.txt", myStream)), JSZip приостанавливает его и ждет что-то его использовать (вызов zip.generateNodeStream() или геттер, например).

Так что вы можете сделать (в текущем v3.1.2), чтобы ограничить использование памяти, чтобы добавить все ресурсы в поток и вызвать zip.generateNodeStream({streamFiles:true}). Основной недостаток заключается в том, что вы открываете соединения с вашими веб-службами, и вы можете поражать тайм-аут (пусть говорят в последнем файле) при потоковой передаче первых файлов (или, что еще хуже, в зависимости от того, как обрабатывается .pause() входным потоком).

Что касается streamFiles и комментариев к вопросу: формат zip хорошо подходит для потоковой передачи. Как указано в the documentation, опция streamFiles определяет, где записывается размер/crc32 файла внутри zip-файла: перед данными (но нам нужно временно удерживать файл в памяти для их вычисления) или после данных (поток все, поместите вычисленные значения в конец).