Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取文件,然后使用node.js删除该文件_Node.js_Fs - Fatal编程技术网

读取文件,然后使用node.js删除该文件

读取文件,然后使用node.js删除该文件,node.js,fs,Node.js,Fs,我正在尝试使用nodeJS执行以下操作: 启动一个可执行文件(可执行文件然后创建一个timestamp_Question.txt文件),读取创建的.txt文件并将文本返回到我的前端。接受用户输入并使用包含用户输入的新名称创建一个新的timestamp_Answer.txt文件,然后删除原始txt文件 除了删除原始文件外,其他一切似乎都正常工作,该文件出现以下错误 错误:EBUSY:资源正忙或已锁定,取消链接'c:\projects\pizzabox\95912\u Questi on.txt'

我正在尝试使用nodeJS执行以下操作:

启动一个可执行文件(可执行文件然后创建一个timestamp_Question.txt文件),读取创建的.txt文件并将文本返回到我的前端。接受用户输入并使用包含用户输入的新名称创建一个新的timestamp_Answer.txt文件,然后删除原始txt文件

除了删除原始文件外,其他一切似乎都正常工作,该文件出现以下错误

错误:EBUSY:资源正忙或已锁定,取消链接'c:\projects\pizzabox\95912\u Questi on.txt' 错误(本机)

以下是我的服务器代码的各个部分:

正在启动.exe文件:

  startProgram: function(req, res){
    var date = new Date().toLocaleTimeString();
    date = date.replace(/\D/g,'');
    exec('C:/projects/pizzabox/server/webserver/Pizza_page_server.exe', [date], function(err, data) {  
     console.log(err)
    });
    res.send(date)  /// front end needs date value to track file as date is attached to created txtfile
  }
前端请求exe创建的txt的内容:

 getDocument: function(req,res){
    console.log('file requested', req.params.dateStamp);
    var directory = 'C:/projects/pizzabox/'
    var fileCode = req.params.dateStamp.toString()
    var fileSuffix = "_Question.txt"
    var file = directory+fileCode+fileSuffix
    console.log('file is', file);


    while(!fs.existsSync(file)){};
    fs.readFile(file, 'utf8', function(err,data){
      if (err) throw err;
      console.log('read ', data);
      res.send(data)
    });
前端提交数据以创建新的timestamp_Answer.txt文件并删除旧的timestamp_Question.txt文件:

  sendValue: function(req,res){
    console.log('got value', req.body.value, " questionNumber ", req.body.questionNumber, "timestamp ", req.body.timestamp);
    fs.appendFile(req.body.timestamp+'_Answer.txt', "Question_Num:"+req.body.questionNumber+"\nAnswer_Val:"+req.body.value, function(err){
      if(err) throw err;
      console.log('file created!');

      fs.unlink(req.body.timestamp+'_Question.txt', function(err){
        if (err) throw err;
        console.log('question file deleted');
      })
    })
  }

为什么取消链接无法访问该文件?fs.readFile()是否在文件完成后关闭/退出

这里似乎至少有一个比赛条件。仅仅因为
fs.fileExistsSync()
看到某个文件存在,并不意味着.exe已完成对该文件的写入或已关闭该文件。因此,很可能会在另一个进程仍打开文件时调用您的
fs.readFile()

您可能想重新思考所有操作的顺序

首先,您现在的设计是单用户设计。您的服务器一次只能由一个用户使用,因为您无法区分来自不同用户的请求

其次,您应该转向一种更有目的性的顺序设计,而不是试图使用文件系统中存在的文件作为现在可以执行某些先前操作的证据

第三,关闭
while(!fs.existsSync(file)){}永远不会用于任何东西,因为它会停止服务器中任何类型的请求、计时器或任何事件的所有处理,直到该文件存在为止。而且,它可能占用了所有的CPU。它从未在多用户服务器中使用过

您没有真正描述您试图设计的整个客户机/服务器流程,也没有描述这是一个单用户系统还是打算最终用于多用户,因此我们很难就架构重新设计的具体方向提出建议

您可能可以做一个简单的改进,在
.exe
完成之前不将日期返回给客户端,这有望在.exe完成之前阻止客户端请求下一步:

  startProgram: function(req, res){
    var date = new Date().toLocaleTimeString();
    date = date.replace(/\D/g,'');
    exec('C:/projects/pizzabox/server/webserver/Pizza_page_server.exe', [date], function(err, data) {  
     if (err) {
          console.log(err);
          res.sendStatus(500);
     } else {
          // don't send this until the .exe is done
          res.send(date)  // front end needs date value to track file as date is attached to created txtfile
     }
    });
  }

仅供参考,这是
而(!fs.existsSync(file)){}
是可怕的服务器端代码。这将“挂起”您的服务器,使其无法执行任何其他操作,并且在该文件存在之前不会响应任何其他请求。它可能还会占用您的CPU,谁知道它会对您的硬盘驱动器造成什么影响呢?您的
fs.unlink()
code引用
req.body.timestamp+''.\u Question.txt'
,但是您没有显示任何使用该文件名的其他代码,因此我们很难看到是什么导致了该问题。您显示了一个
fs.appendFile()
操作,但它引用了另一个文件
req.body.timestamp+''u Answer.txt'
。此外,请不要在异步回调中编写使用
if(err)throw err
的代码。它没有做任何有用的事情,因为它只是异步地抛出到
fs
模块中,您永远无法捕获它。编写向当前请求发送错误响应的实际错误处理程序。如果您在运行
C:/projects/pizzabox/server/webserver/Pizza\u page\u server.exe
时创建此文件,则服务器不会等待该操作完成,因此在该操作仍在运行时可能会发生后续的客户端/服务器操作。@jfriend00 fs.unlink()引用req.body.timestamp+“\u Question.txt”以使用fs.existsSync(file)检查的代码前面的文件为目标我看到你也不喜欢,你建议我用什么来代替它,因为我需要服务器确保我的.exe已经创建了文件,这样我就可以读取它,而不需要while循环节点在创建文件之前尝试读取该文件。至于fs.appendFile()我正在使用它创建一个新文件,创建xxx_question.txt后的exe将等待该文件被删除,并在继续之前读取xxx_answer.txt。我无法等待返回日期,因为.exe仍然存在,我可能需要更好地解释它的功能。>服务器启动.exe传递xxx(xxx是时间戳)>.exe创建XXX_Question.txt>服务器读取XXX_Question.txt并将文本发送到客户端,以便用户可以响应问题并将响应发送回服务器>服务器创建XXX_Question.txt并删除XXX_Question.txt>。exe读取XXX_Question.txt并创建新的XXX_Question.txt(XXX仍然是原始值)>重复此操作,直到.exe停止提示并生成十六进制文件供用户使用DL@AaronManill-好的,您当前的设计不起作用-您有一个争用条件和几个其他问题。您需要一种更好的方式让exe和express程序进行通信,而不是循环检查文件系统。我有几十个进程内通信您可以使用的方法。我的第一个问题是,为什么问题生成逻辑一开始就在一个单独的exe中,而它可能只是在您的Express程序中,而且事情可能会简单得多。@AaronManill-如果不是,请将您的exe设置为一个只有本地访问权限的小型http服务器,并让您的Express程序发送请求并获取资源ponses。似乎也没有理由需要为每个日期戳启动一个新的exe。它可能只是一个小型服务器,用于处理问题请求和回答请求(不必在文件系统中,也不必通过轮询文件系统来发现)。循环