26

我想要做的是读取一个文件,然后在我写入文件时能够使用该信息执行其他操作。例如:

读取文件写入文件,同时进行MD5哈希、数字签名等。

我可以使用 fs.readfile 和 fs.writefile 作为一项操作,只需将文件从 Web 服务器复制到我的计算机,但我认为我仍然不能执行这些相同的操作。无论如何,跳过中间的东西。如何使用 fs.readfile 和 writefile 创建两个单独的函数来复制文件?这是我一直在做的事情,是的,我已经广泛阅读了这些论坛以寻找答案。

var fs = require('fs');



function getData(srcPath) { 
fs.readFile(srcPath, 'utf8', function (err, data) {
        if (err) throw err;
        return data;
        }
    );
}


function writeData(savPath, srcPath) {
        fs.writeFile (savPath, (getData(srcPath)), function(err) {
        if (err) throw err;
            console.log('complete');
        }
    );
}
//getData ('./test/test.txt');
writeData ('./test/test1.txt','./test/test.txt');

我希望能够下载任何类型的文件并制作原始副本,并将 md5 哈希等附加到 JSON 文件。不过,这可能是以后的问题。

4

3 回答 3

27

正如 dandavis 在他的评论中所建议的那样,readFile什么都不做,因为它是一个异步调用。查看此答案以获取有关这意味着什么的更多信息。

简而言之,异步调用永远不会等待结果返回。在您的示例中,getData不等待readFile()返回您想要的结果,而是会立即完成。异步调用通常通过传递 来处理,这是和callbacks的最后一个参数。readFilewriteFile

无论如何,有两种方法可以做到这一点:

1.异步执行(这是正确的方法):

function copyData(savPath, srcPath) {
    fs.readFile(srcPath, 'utf8', function (err, data) {
            if (err) throw err;
            //Do your processing, MD5, send a satellite to the moon, etc.
            fs.writeFile (savPath, data, function(err) {
                if (err) throw err;
                console.log('complete');
            });
        });
}

2.同步进行。您的代码不必更改太多,您只需要分别替换readFileand writeFilebyreadFileSyncwriteFileSync警告:使用这种方法不仅违背了最佳实践,而且违背了使用 nodejs 的目的(当然,除非你有非常正当的理由)。

编辑:根据 OP 的要求,这是一种分离这两种方法的可能方法,例如,使用回调:

function getFileContent(srcPath, callback) { 
    fs.readFile(srcPath, 'utf8', function (err, data) {
        if (err) throw err;
        callback(data);
        }
    );
}

function copyFileContent(savPath, srcPath) { 
    getFileContent(srcPath, function(data) {
        fs.writeFile (savPath, data, function(err) {
            if (err) throw err;
            console.log('complete');
        });
    });
}

这样,您将读取部分 (in getFileContent) 与复制部分分开。

于 2013-07-15T02:12:19.500 回答
5

我最近不得不使用它,所以我将verybadallocs 的答案转换为promises。

function readFile (srcPath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(srcPath, 'utf8', function (err, data) {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
}

function writeFile (savPath, data) {
  return new Promise(function (resolve, reject) {
    fs.writeFile(savPath, data, function (err) {
      if (err) {
        reject(err)
      } else {
        resolve()
      }
    })
  })
}

然后使用它们很简单。

readFile('path').then(function (results) {
  results += ' test manipulation'
  return writeFile('path', results)
}).then(function () {
  //done writing file, can do other things
})

异步/等待的用法

const results = await readFile('path')
results += ' test manipulation'
await writeFile('path', results)
// done writing file, can do other things
于 2017-12-19T14:59:55.610 回答
0

要以非阻塞或异步方式读写文件,您可以使用 es6 或更高版本的高级功能,如 Promise 或 Async/await,但您必须留意Polyfills ( https://javascript.info/polyfills ) 或如果只有几个读/写,你可以使用回调地狱。

function readFiles(){
    fs.readFile('./txt/start.txt', 'utf-8', (err, data1)=>{
        if(err) return console.log(err);
        fs.readFile(`./txt/${data1}.txt`, 'utf-8', (err, data2)=>{
            if(err) return console.log(err);
            fs.readFile('./txt/append.txt', 'utf-8', (err, data3)=>{
                if(err) return console.log(err);
                writeFile('./txt/final.txt', `${data2}\n${data3}`);
            });
        });
    });
}

function writeFile(path, data){
    fs.writeFile(path,data,'utf-8',err=>{
        if(err){
            console.log(err);
        }
    })
}
readFiles();
于 2020-05-14T09:17:53.020 回答