Javascript FileSystem函数无法按预期工作[重复]

Posted

技术标签:

【中文标题】Javascript FileSystem函数无法按预期工作[重复]【英文标题】:Javascript FileSystem function not working as intended [duplicate] 【发布时间】:2021-11-08 04:38:45 【问题描述】:

我有一个简单的代码来将一个 js 列表写入一个 js 文件。

// Requiring fs module in which
// writeFile function is defined.
var fs = require('fs');

// first overwrite any pre-existing file with the start of the list
fs.writeFile('Output.js', 'export const addressPoints = [', function (err) 
  if (err) throw err;
  console.log('Create file Output.js');
);

for (let i = 0; i < 100; i++) 
    // var string_row = "[" + latlon_datum1_row[i] + "],";
    var string_row = "HI"
    console.log(string_row);
    fs.appendFile('Output.js', string_row, function (err) 
        if (err) throw err;
        console.log('Writing file contents line', i);
    );


fs.appendFile('Output.js', '];', function (err) 
if (err) throw err;
    console.log('Append file Output.js');
);

可以分为三个部分,一个初始组件创建新的js脚本并添加'export const addressPoints = ['。之后,运行一个 for 循环来写入列表中的项目,最后是 '];'附加到文件末尾。

很奇怪,代码没有按预期工作。人们会期望控制台日志看起来像

Create file Output.js
Writing file contents line 1
Writing file contents line 2
Writing file contents line 3
...
Writing file contents line 99
Append file Output.js

但是,输出被打乱并以错误的顺序写入(显示最后几行):

...
Writing file contents line 96
Writing file contents line 97
Writing file contents line 98
Append file Output.js
Writing file contents line 99
Writing file contents line 91
Writing file contents line 79
Writing file contents line 68

有没有一种方法可以更快地做到这一点?如果不是,为什么会出现这个错误?我认为它与 fs 闭包有关,但我对 js 不太熟悉。

【问题讨论】:

您最好打开文件一次并在它打开时写下您需要写的内容,然后在最后关闭它。每次执行“追加”操作时,操作系统都必须找到并重新打开该文件。 谢谢你们!我已经设法解决了。 【参考方案1】:

console.log 详细信息的加分项。

如您所见,日志的顺序错误。这是由于 nodejs 和 javascript 的异步特性。

您需要使用回调或承诺来“等待”上一个操作的结果。

示例:读取文件并打印其内容

不正确

fs.readFile('/tmp/foo.txt',function (err, data) 
);

console.log('data is...');

正确

fs.readFile('/tmp/foo.txt',function (err, data) 
  console.log('data is:'+data);
);

如您所见,readFile 和几乎所有 nodejs 函数都是异步的。这意味着我们不能像 java、c# 或 python 那样以顺序或同步模式思考。在这种情况下,readFile 需要在读取文件时执行一个函数

function (err, data) 
  console.log('data is:'+data);

回调

工作传递函数将在异步操作之后执行。

var fs = require('fs');

fs.writeFile('Output.js', 'export const addressPoints = [', function (err) 
  if (err) throw err;
  console.log('Create file Output.js');

  //execute after file was updated
  var newContent = "";
  for (let i = 0; i < 100; i++) 
    var string_row = "HI"
    console.log(string_row);
    newContent += string_row+"\n";    
  
  newContent += "];\n";      
  
  fs.appendFile('Output.js', newContent, function (err) 
    if (err) throw err;
    console.log('Output.js was updated');
  );
  
);

或者更易读一点

var fs = require('fs');

fs.writeFile('Output.js', 'export const addressPoints = [', createCustomFile);

function createCustomFile(err, data)
  //logic here

缺点

如果你需要执行更多的操作,你会做噩梦

承诺和等待

一种编写更具可读性(继续异步)代码与嵌套回调的方法

var fs = require('fs');

async function main()
  await fs.promises.writeFile('Output.js', 'export const addressPoints = [');
  console.log('Create file Output.js');

  for (let i = 0; i < 100; i++) 
      var string_row = "HI"
      console.log(string_row);
      await fs.promises.appendFile('Output.js', string_row);
      console.log('Writing file contents line', i);
  
  
  await fs.promises.appendFile('Output.js', '];');
  console.log('Append file Output.js');


//launch
//don't forget to catch async exceptions here!
main().catch(e =>  console.error(e); process.exit(1) )

【讨论】:

以上是关于Javascript FileSystem函数无法按预期工作[重复]的主要内容,如果未能解决你的问题,请参考以下文章

为什么没有boost :: filesystem :: move_file?

无法进入子目录

构建开发失败:无法将属性“fileSystem”设置为 null

错误:使用已删除的函数 boost::filesystem3::directory_iterator

SonarQube 在 Azure Pipelines 上失败,无法加载组件类 org.sonar.scanner.scan.filesystem.InputComponentStore

使用带有 linux 的 std::filesystem 是坏的还是文件系统树无法访问?