【问题标题】:wait for writestream to finish before executing next function在执行下一个函数之前等待 writestream 完成
【发布时间】:2020-07-03 16:45:32
【问题描述】:

我有两个功能。 第一个函数读取文件夹中的所有文件并将其数据写入新文件。 第二个函数将该新文件(函数 1 的输出)作为输入并创建另一个文件。因此它必须等到函数 1 的写入流完成。

const fs = require('fs');
const path = require('path');

function f1(inputDir, outputFile) {
    let stream = fs.createWriteStream(outputFile, {flags:'a'}); // new data should be appended to outputFile piece by piece (hence flag a)
    let files = await fs.promises.readdir(inputDir);

    for(let file of files) {
        let pathOfCurrentFile = path.join(inputDir, file);
        let stat = fs.statSync(pathOfCurrentFile);
        if(stat.isFile()) {
            data = await fs.readFileSync(pathOfCurrentFile, 'utf8');

            // now the data is being modified for output
            let result = data + 'other stuff';
            stream.write(result);
        }
    }
    stream.end();
}

function f2(inputFile, outputFile) {
    let newData = doStuffWithMy(inputFile);
    let stream = fs.createWriteStream(outputFile);
    stream.write(newData);
    stream.end();
}

f1('myFiles', 'myNewFile.txt');
f2('myNewFile.txt', 'myNewestFile.txt');

会发生什么:

  • 'myNewFile.txt'(f1 的输出)已正确创建
  • “myNewestFile.txt”已创建,但为空或仅包含一两个单词(应包含长文本)

当我在执行 f2 之前使用超时,它可以正常工作,但我不能使用超时,因为 inputDir 中可能有数千个输入文件,因此我需要一种动态执行它的方法。

我已经尝试过异步/等待、回调、承诺等,但这些东西对我来说似乎有点高级,我无法让它工作。

还有什么我可以尝试的吗?

【问题讨论】:

  • 为什么使用半异步半同步文件I/O?任选其一。
  • @jfriend00 抱歉,这是尝试不同事物的结果
  • @jfriend00 这看起来像 100% 同步?
  • 100% 同步,您只需使用fs.openSync() 打开文件并使用fs.writeSync()。这段代码在什么类型的应用程序中?它是一个服务器进程吗?还是只是一个用户处理脚本?
  • 仅供参考,您显示的代码甚至不会运行,因为您在非异步函数中显示 await

标签: node.js fs synchronous


【解决方案1】:

既然您询问了同步版本,这就是它的样子。这应该只在单个用户脚本或启动代码中使用,而不是在正在运行的服务器中。服务器应该只使用异步文件 I/O。

// synchronous version
function f1(inputDir, outputFile) {
    let outputHandle = fs.openSync(outputFile, "a");
    try {
        let files = fs.readdirSync(inputDir, {withFileTypes: true});
        for (let f of files) {
            if (f.isFile()) {
                let pathOfCurrentFile = path.join(inputDir, f.name);
                let data = fs.readFileSync(pathOfCurrentFile, 'utf8');
                fs.writeSync(outputHandle, data);
            }
        }
    } finally {
        fs.closeSync(outputHandle);
    }
}

function f2(inputFile, outputFile) {
    let newData = doStuffWithMy(inputFile);
    fs.writeFileSync(outputFile, newData);
}

f1('myFiles', 'myNewFile.txt');
f2('myNewFile.txt', 'myNewestFile.txt');

【讨论】:

  • @c0rnfl4k3s - 这回答了你的问题吗?如果是这样,您可以通过单击答案左侧的复选标记向社区表明这一点。这也将为您在此处遵循正确的程序赢得一些声誉积分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 2020-05-25
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多