题 在Node.js中编写文件


我一直在尝试使用Node.js找到写入文件的方法,但没有成功。我怎样才能做到这一点?


1147
2018-03-23 00:25


起源




答案:


这里有很多细节 文件系统API。最常见的方式(据我所知)是:

var fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
    if(err) {
        return console.log(err);
    }

    console.log("The file was saved!");
}); 

1813
2018-03-23 01:50



我已经使用Node测试了这个脚本,我尝试将文件路径更改为“/ home /”,但是我收到以下错误: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' }  如何修改此脚本以使其在外部工作 /tmp? - Anderson Green
另请注意,您可以使用fs.writeFileSync(...)同步完成相同的操作。 - David Erwin
也许它有点旧,但是@AndersonGreen,你需要以root用户身份或chmod / home运行节点,以允许对当前节点进程所有者的R / W权限(你的用户名很难),这样你就可以编写文件了 - Denys Vitali
实际上,@ DenysVitali,问题在于jane应该无法写入任何文件 /home/...。通常该目录是755 root:wheel(或其他)。如果node想要将文件写为jane,那么写入会更容易 /home/jane/test.txt。更改 /home 比755更宽容的东西是一个巨大的错误。 - jane arc
@JaneAvriette好吧,因为他想保存文件 /home 目录我建议chmod它。我知道它可能会产生安全问题。但是,如果用户想要保存,那就是解决方案。 P.S:我同意你的说法(: - Denys Vitali


目前有三种写文件的方法:

  1. fs.write(fd, buffer, offset, length, position, callback

    您需要等待回调以确保将缓冲区写入磁盘。它没有缓冲。

  2. fs.writeFile(filename, data, [encoding], callback)

    所有数据必须同时存储;你不能执行顺序写入。

  3. fs.createWriteStream(path, [options]

    创建一个 WriteStream,这很方便,因为您不需要等待回调。但同样,它没有被缓冲。

一个 WriteStream顾名思义,就是一个流。根据定义,流是“缓冲区”,包含沿一个方向移动的数据(源►目的地)。但是可写流不一定是“缓冲的”。写入时,流被“缓冲” n 时间和时间 n+1,流将缓冲区发送到内核(因为它已满并需要刷新)。

换一种说法: “缓冲区”是对象。它是否“缓冲”是该对象的属性。

如果你看代码,那么 WriteStream 继承自可写 Stream 目的。如果你注意,你会看到他们如何冲洗内容;他们没有任何缓冲系统。

如果您编写一个字符串,它将转换为缓冲区,然后发送到本机层并写入磁盘。在编写字符串时,它们不会填充任何缓冲区。所以,如果你这样做:

write("a")
write("b")
write("c")

你在做:

fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))

那是  调用I / O层。虽然您使用的是“缓冲区”,但数据不会被缓冲。缓冲流可以: fs.write(new Buffer ("abc")),一次调用I / O层。

截至目前,在Node.js v0.12(2015年2月6日公布的稳定版)中现在支持两个功能: cork() 和 uncork()。看来这些函数最终会允许你缓冲/刷新写调用。

例如,在Java中有一些提供缓冲流的类(BufferedOutputStreamBufferedWriter...)。如果写入三个字节,这些字节将存储在缓冲区(内存)中,而不是仅为三个字节进行I / O调用。当缓冲区已满时,内容将被刷新并保存到磁盘。这提高了性能。

我没有发现任何东西,只记得应该如何进行磁盘访问。


434
2017-08-05 15:28



+1 - 很好的解释。对于写入流,仔细阅读文档非常重要。如果返回false或者关闭,那么调用writer.once('drain',function(){})很重要,或者我错过了在进程结束时没有耗尽的行。 - bryanmac
你有机会提供一个如何使用的例子 cork() 和 uncork() 对于我们这些想要尝试预发布0.11节点的人? - professormeowingtons
截至目前,Node v0.12是稳定的。 - aug


你当然可以使它更先进一点。无阻塞,写入碎片,而不是一次写入整个文件:

var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
  stream.write("My first row\n");
  stream.write("My second row\n");
  stream.end();
});

189
2017-12-16 14:40



传递给stream.once的回调的'fd'变量是什么? - Scott David Tesler
@ScottDavidTesler文件描述符,这样您就可以在完成后关闭流。 - Alexey Kamenskiy
我什么时候关闭流?为什么这种非阻塞?只是好奇,我正在尝试写入日志文件。 - BigOmega
当你完成stream.writes()时,你总是可以做一个stream.end()。我将它添加到示例中。 - Fredrik Andersson
@JoLiss你将不得不等待它。 - Fredrik Andersson


var path = 'public/uploads/file.txt',
buffer = new Buffer("some content\n");

fs.open(path, 'w', function(err, fd) {
    if (err) {
        throw 'error opening file: ' + err;
    }

    fs.write(fd, buffer, 0, buffer.length, null, function(err) {
        if (err) throw 'error writing file: ' + err;
        fs.close(fd, function() {
            console.log('file written');
        })
    });
});

38
2017-11-07 20:54



这演示了如何使用较低级别的fs操作来编写文件。例如,您可以保证文件何时写入磁盘并释放文件描述符。 - Sean Glover


我喜欢 ./articles/file-system的索引

它对我有用。

也可以看看 如何在node.js中写入文件?

fs = require('fs');
fs.writeFile('helloworld.txt', 'Hello World!', function (err) {
    if (err) 
        return console.log(err);
    console.log('Wrote Hello World in file helloworld.txt, just check it');
});

helloworld.txt的内容:

Hello World!

更新:
如在Linux节点中写入当前目录,似乎在其他一些目录中没有,所以我添加此注释以防万一:
用这个 ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH); 获取文件的写入位置。


20
2017-10-23 07:54



在哪里可以找到helloworld.txt文件?我无法在任何文件夹中找到它...谢谢。 - Kai Feng Chew
在您运行脚本的文件夹中 - Sérgio
这很奇怪......我无法在任何地方找到它。它会隐藏吗?再次感谢〜 - Kai Feng Chew
node test.js cat helloworld.txt Hello World! - Sérgio
我刚发现它。用这个 ROOT_APP_PATH = fs.realpathSync('。');的console.log(ROOT_APP_PATH);得到我写的文件的位置。谢谢。 - Kai Feng Chew


 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

例如:读取文件并写入另一个文件:

  var fs = require('fs');
    var path = process.cwd();
    fs.readFile(path+"\\from.txt",function(err,data)
                {
                    if(err)
                        console.log(err)
                    else
                        {
                            fs.writeFile(path+"\\to.text",function(erro){
                                if(erro)
                                    console.log("error : "+erro);
                                else
                                    console.log("success");
                            });
                        }
                });

5
2018-05-17 05:54



你把数据写入“to.text”的地方? - Ravi Shanker Reddy


同步写入

fs.writeFileSync(文件,数据[,选项])

fs = require('fs');

fs.writeFileSync("synchronous.txt", "synchronous write!")

异步写入

fs.writeFile(文件,数据[,选项],回调)

fs = require('fs');

fs.writeFile('asynchronous.txt', 'asynchronous write!', (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

哪里

file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>

值得阅读官方文件系统(fs) 文档


4
2017-10-01 05:39





这里我们使用w +来读/写两个动作,如果找不到文件路径,它将自动创建。

fs.open(path, 'w+', function(err, data) {
    if (err) {
        console.log("ERROR !! " + err);
    } else {
        fs.write(data, 'content', 0, 'content length', null, function(err) {
            if (err)
                console.log("ERROR !! " + err);
            fs.close(data, function() {
                console.log('written success');
            })
        });
    }
});

内容意味着您必须写入文件及其长度'content.length'。


2
2017-09-01 11:06