【问题标题】:Understanding node.js require('fs') vs require('fs').promises;了解 node.js require(\'fs\') 与 require(\'fs\').promises;
【发布时间】:2023-02-19 14:45:39
【问题描述】:

我有两种方法。

第一个读取文件并将其作为纯文本写入该文件。第二个将文件作为流写入。

为了让它工作,我不得不在 require 中添加 fs 两次。

const fs = require('fs').promises;
const fs2 = require('fs');

我试图了解其中的区别以及为什么我需要两次。但似乎没有 promise 的 fs 没有能力使用 createWriteStream 而没有 .promises 的 fs 没有能力使用 writeFile

/**
 * Serializes credentials to a file compatible with GoogleAUth.fromJSON.
 *
 * @param {OAuth2Client} client
 * @return {Promise<void>}
 */
async function saveCredentials(client) {
    const content = await fs.readFile(CREDENTIALS_PATH);
    const keys = JSON.parse(content);
    const key = keys.installed || keys.web;
    const payload = JSON.stringify({
        type: 'authorized_user',
        client_id: key.client_id,
        client_secret: key.client_secret,
        refresh_token: client.credentials.refresh_token,
    });
    await fs.writeFile(TOKEN_PATH, payload);
}

第二个以流的形式写入文件

/**
 * Download file
 * @param {OAuth2Client} authClient An authorized OAuth2 client.
 */
async function downloadFile(authClient) {

    const service = google.drive({version: 'v3', auth: authClient});
    const fileStream = fs2.createWriteStream("test.txt")
    fileId = FILEID;
    try {
        const file = await service.files.get({
            fileId: fileId,
            alt: 'media',
        }, {
                responseType: "stream"
            },
            (err, { data }) =>
                data
                    .on('end', () => console.log('onCompleted'))
                    .on('error', (err) => console.log('onError', err))
                    .pipe(fileStream)
        );
    } catch (err) {
        // TODO(developer) - Handle error
        throw err;
    }
}

请注意,这确实有效,我只是想围绕 Node.js 进行思考。

【问题讨论】:

    标签: javascript node.js google-api-nodejs-client


    【解决方案1】:

    fs.promises 包含 fs 上的接口的一个子集,但使用基于承诺的接口而不是普通的回调式接口。

    有些东西不能很好地转化为承诺或没有自然的基于承诺的界面,例如 fs.createReadStream() 只能在 fs 上使用。请注意,fs.createReadStream() 返回一个流并使用流上的事件,而不是普通的回调(不能很好地转换为承诺)。因此,它的界面在fs 上保持不变,并且在fs.promises 上没有重复。

    许多东西都可以在不同的界面中使用:

    fs.writeFile(filename, data, callback);     // plain callback interface
    

    或者

    await fs.promises.writeFile(filename, data)    // promise interface
    

    大多数时候,我只能使用 fs.promises 接口并执行以下操作:

    const fsp = require('fs').promises;
    

    但有时,你需要两者,我会这样做:

    const fs = require('fs');
    const fsp = fs.promises;
    

    请记住,fs.promises 不能完全替代 fs它是fs 模块中某些(但不是全部)方法的替代(基于承诺)接口。

    fsp.open() 等其他接口已得到增强并转换为 fs.promises 接口中的承诺,它现在返回一个承诺,该承诺解析为面向对象的 fileHandle 对象,而 fs.open() 仅接受将传递文件描述符的回调.


    所以,我的操作方式是在fs.promises界面中查看我在做什么。如果它在那里,我在那里使用它并使用它的承诺。

    如果不存在,则返回fs界面获取我需要的内容。


    我建议您不要编写将符号 fs 用于 fs.promises 的代码。这会使阅读或处理您的代码的人感到困惑,因为他们可能认为名为 fs 的符号是 fs 接口。这就是为什么我在代码中使用fs作为fs接口,使用fsp作为fs.promises接口。

    【讨论】:

    • 我真的可以使用像你这样的人来教我 node.js。你的解释很有道理。谢谢你消除了我的困惑。
    【解决方案2】:

    难道说 fs promise writeFile 和 fs writeFileSync 是一回事吗?或者更确切地说,会以同样的方式行事吗?

    【讨论】:

      猜你喜欢
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 2012-02-15
      • 2018-10-11
      • 1970-01-01
      相关资源
      最近更新 更多