了解node.js require('fs') 与 require('fs').promises;

DaI*_*mTo 12 javascript node.js google-api-nodejs-client

我有两个方法。

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

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

const fs = require('fs').promises;
const fs2 = require('fs');
Run Code Online (Sandbox Code Playgroud)

我试图理解其中的区别以及为什么我需要两次。但似乎没有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);
}
Run Code Online (Sandbox Code Playgroud)

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

/**
 * 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这确实有效,我只是想了解 Node.js。

jfr*_*d00 21

fs.promises包含 on 接口的子集fs,但使用基于 Promise 的接口,而不是普通的回调式接口。

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

许多东西都可以在不同的接口中使用:

fs.writeFile(filename, data, callback);     // plain callback interface
Run Code Online (Sandbox Code Playgroud)

或者

await fs.promises.writeFile(filename, data)    // promise interface
Run Code Online (Sandbox Code Playgroud)

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

const fsp = require('fs').promises;
Run Code Online (Sandbox Code Playgroud)

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

const fs = require('fs');
const fsp = fs.promises;
Run Code Online (Sandbox Code Playgroud)

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

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


所以,我的操作方式是在界面中查找fs.promises我正在做的事情。如果它在那里,我就在那里使用它并使用它的承诺。

如果没有,则返回到fs我需要的界面。


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