Node.js - tar 文件的 exec 命令第一次工作正常,但在后续执行时产生损坏的 tar 内容

标签 node.js linux tar

我正在使用 Node.js 构建一个 Web 应用程序,现在我需要生成一个 PDF 目录的 tar 存档。该应用程序在运行 Ubuntu 14.04 服务器的 VM 上运行。我执行此操作的代码如下所示:

function tarDirectory(path, token, callback) {
  var exec = require('child_process').exec;
  var cmd = 'cd ' + path + ' && tar -cvf genericName-' + token + '.tar' + ' ' + token;

  exec(cmd, function(error, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
    if (error) {
      console.error(error);
    }
    if(callback) callback();
  });
}

此 tarDirectory 函数由以下代码调用:

router.post('/files/generate', function(req, res, next) {
  IDList = req.body['IDs[]'];
  token = req.body['token'];

  // if just a single file being generated
  if (typeof req.body['IDs[]'] === "string"){
      filehelper.generateFile(IDList[0], req.app.locals.site.basedir + "temp/", token);
  }
  // if multiple files being generated
  else {
    IDList.forEach(function(id) {
      filehelper.generateFile(id, req.app.locals.site.basedir + "temp/", token);
    });
  }
  filehelper.tarDirectory(req.app.locals.site.basedir + "temp/", token, res.end);
});

该代码需要一个带有动态数据的发布请求,该动态数据是通过在我的网络应用程序中单击按钮生成的,然后将根据数据创建文件并将其压缩到一个目录中。这一切都很好……第一次。当我一段时间内第一次单击该按钮时,会生成 tar,当我打开它时,客户端 PDF 与服务器上的相同。但是,当我在大约一个小时内再次单击时,我收到了一个 tar 文件,但是当我打开存档并将其解压缩时,PDF 全部损坏并且大约是预期字节大小的一半。我在这里不知所措......我怀疑这可能与流关闭处理不当有关,但我不确定。

这是将 PDF 生成到一个目录中的代码,生成后将其打包:

function generateFile(id, path, token) {
  var dirPath = path + token;
  var filePath = path + token + "/file" + id + ".pdf";

  console.log("creating file for: " + id);

  try{
    fs.statSync(dirPath).isDirectory();
  } catch (err) {
    fs.mkdirSync(dirPath);
  }
  // start the file pdf generation
  file = new PDFDocument();
  output = fs.createWriteStream(filePath);
  output.on('close', function(){
    return;
  });

  file.pipe(output);

  // handle the intricacies of the file generation
  file.text("file" + id + ".pdf");

  // end the file
  file.end();
}

最佳答案

  1. 压缩前 pdf 文件是否一切正常?
  2. 在您的 generateFile 函数中,您有 WriteStream,它是异步的。但是,您将此函数调用为 sync.,并且在 pdf 生成完成之前没有等待就开始 .tar 压缩,这可能会导致此问题。
  3. 作为建议:尝试用 promise 包装 generateFile,或者迭代 async.,并且仅在所有文件生成完成后才开始压缩。

bluebird 示例:

var Promise = require('bluebird');

function generateFile(id, path, token) {
  return new Promise(function(resolve, reject) {
  var dirPath = path + token;
  var filePath = path + token + "/file" + id + ".pdf";

  console.log("creating file for: " + id);

  try{
    fs.statSync(dirPath).isDirectory();
  } catch (err) {
    fs.mkdirSync(dirPath);
  }
  // start the file pdf generation
  file = new PDFDocument();
  output = fs.createWriteStream(filePath);
  output.on('close', function(){
    return resolve();
  });

  output.on('error', function(error) {
    return reject(error);
  });

  file.pipe(output);

  // handle the intricacies of the file generation
  file.text("file" + id + ".pdf");

  // end the file
  file.end();
  });
}

Pdfs 生成和压缩。

 var Promise = require('bluebird');

    ....

    //IDList.forEach(function(id) {
    //      filehelper.generateFile(id, req.app.locals.site.basedir + "temp/", //token);});

    //replace with

    Promise.map(IDList, function(id) {
      return filehelper.generateFile(id, req.app.locals.site.basedir + "temp/", token);
    })
    .then(function() {
    //all files are ready, start compressing
    })
    .catch(function(error) {
    //we have error
    });

关于Node.js - tar 文件的 exec 命令第一次工作正常,但在后续执行时产生损坏的 tar 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38826925/

相关文章:

javascript - 通过socket.io(JavaScript & FileReader)上传文件

c - 解决 time.h 中 timespec 的重新定义

linux - 如何归档不同目录中的特定文件?

linux - 通过 ssh 从最新更改的目录中获取 Tar 文件

linux - 为什么 sh 找不到绑定(bind)安装在 docker 容器中的可执行文件

compression - 如何用Pigz解压缩

node.js - 将 Bluebird 用于 Mongoose ,得到 ".bind is not a function"

javascript - Lodash没有方法 'remove'

javascript - 我如何在另一个 EC2 实例上运行部分代码

linux - 如何在 linux bash 脚本中用 "-"char (dash) 声明变量名