конвертировать поток файла zip в файл на диске - PullRequest
0 голосов
/ 22 января 2020

У меня есть приложение Node (называемое MiddleOne), из которого я установил другое приложение Node (называемое BiServer). BiServer имеет только 1 маршрут следующим образом

app.get("/", (req, res) => {
  const file = `./zipFiles.zip`;
  return res.download(file);
});

Приложение «MiddleOne» отправляет запрос в «BiServer» и получает файл (ZIP-файл, содержащий один файл. json), однако я не могу чтобы восстановить и сохранить этот файл .zip на моем сервере "MiddleOne".

http
    .get("BiServer:3009", resp => {
      let data = "";

      resp.on("data", chunk => {
        data += chunk;
      });

      resp.on("end", () => {

        fs.writeFile("./filename.zip", data, err => {
          console.log(err ? "Error: " + err : "File saved");
          return res.send("file is saved on server");
        });
      });
    })
    .on("error", err => {
      console.log("Error: " + err.message);
    });

объект данных выше имеет следующее содержимое:

"PK
�T6P    zipFiles/PK�T6P�E8FIzipFiles/zipFiles.json����R*K-*���S�RP�s
W�
��$VZ(Y))股k^zQ�Bjnbf�Bf�BAbq�/W-//PK
�T6P    $zipFiles/
 �c�����c����&�8����PK�T6P�E8FI$ 'zipFiles/zipFiles.json
 K�#����K�#����H�����PK��"

при открытии вновь созданного файла возникает ошибка, что "файл поврежден". Как я могу восстановить ZIP-файл при получении ответа от другого сервера?

1 Ответ

1 голос
/ 22 января 2020

writeFile используется для записи в файл. В вашем случае вы сохраняете данные в виде строки. Наличие zip-расширения для файла не гарантирует, что оно будет zip-файлом. Вы фактически записываете строку (нечитаемые фрагменты) в файл, следовательно, вы не получаете нечитаемый текстовый файл вместо zip-файла. Попробуйте преобразовать чанки в буфер, это должно работать:

http
    .get("BiServer:3009", resp => {
      let chunks = [];

      resp.on("data", chunk => {
        chunks.push(chunk);
      });
     //Don't use end, close is the last event and you should always cleanup in this
      resp.on("close", () => {
        fs.writeFile("./filename.zip", Buffer.concat(chunks), err => {
          console.log(err ? "Error: " + err : "File saved");
          return res.send("file is saved on server");
        });
      });
    })
    .on("error", err => {
      console.log("Error: " + err.message);
    });

Кроме того, он будет занимать много памяти, так как вы загружаете все данные в память перед записью в файл, и если размер файла очень большой, вы столкнется с проблемами, связанными с памятью. Так что вместо сохранения всего файла в памяти. Вы должны попробовать streams , Попробуйте это:

const fs=require("fs");
http
    .get("BiServer:3009", resp => {
      const fileWriteStream=fs.createWriteStream("fileName.zip");
      resp.pipe(fileWriteStream);
      resp.on("close", () => {
        Console.log("File written successfully.")
      });
    })
    .on("error", err => {
      console.log("Error: " + err.message);
    });
...