写入 Node.js 中的文件

Writing to files in Node.js

提问人:Gjorgji 提问时间:3/23/2010 最后编辑:user1280483Gjorgji 更新时间:5/6/2023 访问量:2071291

问:

我一直在尝试找到一种在使用 Node.js 时写入文件的方法,但没有成功。我该怎么做?

JavaScript 节点 .js 文件 表示 fs

评论


答:

2987赞 Brian McKenna 3/23/2010 #1

文件系统 API 中有很多细节。最常见的方法是:

const fs = require('fs');

fs.writeFile("/tmp/test", "Hey there!", function(err) {
    if(err) {
        return console.log(err);
    }
    console.log("The file was saved!");
}); 

// Or
fs.writeFileSync('/tmp/test-sync', 'Hey there!');

评论

34赞 Anderson Green 9/11/2012
我已经使用 Node 测试了这个脚本,并尝试将文件路径更改为“/home/”,但我收到以下错误:如何修改此脚本以使其在外部工作?{ [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } /tmp
158赞 David Erwin 1/24/2013
另请注意,您可以使用 fs.writeFileSync(...) 同步完成相同的操作。
9赞 Denys Vitali 1/3/2014
也许它有点旧,但@AndersonGreen,您需要以 root 或 chmod /home 身份正确运行 node,以允许当前节点进程所有者(您的用户名 tough)获得 R/W 权限,以便您可以编写文件
46赞 jane arc 1/27/2014
实际上,@DenysVitali,问题在于 jane 应该不能将任何文件写入 .通常,该目录是 755 root:wheel(或其他目录)。如果 node 想以 jane 的身份写入文件,写入 会更容易。改用比 755 更宽松的东西是一个巨大的错误。/home/.../home/jane/test.txt/home
11赞 Denys Vitali 1/30/2014
@JaneAvriette 好吧,既然他想将文件保存在目录中,我建议对其进行 chmod。我知道它可能会产生安全问题。但是,如果用户想保存在那里,这就是解决方案。PS:我同意你说的(:/home
313赞 Fredrik Andersson 8/5/2011 #2

你当然可以让它更高级一点。不阻塞,写点点滴滴,不一次性写整个文件:

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();
});

评论

22赞 Scott Tesler 10/18/2012
传递给 stream.once 回调的“fd”变量是什么?
3赞 Alexey Kamenskiy 11/20/2012
@ScottDavidTesler文件描述符,以便您在完成流后能够关闭它。
3赞 MetaGuru 1/3/2013
何时关闭直播?为什么这是非阻塞的?只是好奇,我正在尝试写入日志文件。
1赞 Fredrik Andersson 4/24/2013
我不确定流是否被刷新。我的猜测是有可能按需刷新流。
2赞 Ron Jensen 4/13/2019
此示例为我留下了一个空的“my_file.txt”和 WriteStream 对象的转储。
620赞 22 revs, 9 users 88%Gabriel Llamas #3

目前有三种方法可以写入文件:

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

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

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

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

  3. fs.createWriteStream(path, [options])

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

顾名思义,WriteStream 就是一个流。根据定义,流是“缓冲区”,其中包含沿一个方向(源 ► 目标)移动的数据。但可写流不一定是“缓冲”的。当你写入 times 时,流是“缓冲”的,在 time 时,流将缓冲区发送到内核(因为它已满,需要刷新)。nn+1

换言之:“缓冲区”是对象。它是否“缓冲”是该对象的属性。

如果查看代码,则会发现 继承自可写对象。如果你注意,你会看到他们如何刷新内容;他们没有任何缓冲系统。WriteStreamStream

如果写入字符串,则会将其转换为缓冲区,然后发送到本机层并写入磁盘。写入字符串时,它们不会填满任何缓冲区。因此,如果您这样做:

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

您正在执行以下操作:

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

这是对 I/O 层的三次调用。尽管您使用的是“缓冲区”,但数据不会缓冲。缓冲流将执行: ,对 I/O 层的一次调用。fs.write(new Buffer ("abc"))

截至目前,在 Node.js v0.12(2015 年 2 月 6 日发布的稳定版本)中,现在支持两个函数:cork() uncork()。似乎这些函数最终将允许您缓冲/刷新写入调用。

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

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

评论

7赞 bryanmac 6/19/2014
+1 - 很好的解释。对于写入流,仔细阅读文档非常重要。如果返回 false 或关闭,则调用 writer.once('drain', function(){}) 很重要,否则我错过了进程结束时未排空的行。
4赞 professormeowingtons 8/16/2014
您有机会为我们这些想要尝试预发布 0.11 节点的人提供如何使用的示例吗?cork()uncork()
0赞 aug 4/1/2015
截至目前,Node v0.12 是稳定的。
0赞 drorw 4/19/2019
根据 GitHub 的代码分析,fs.writeFile 似乎是您提到的最受欢迎的函数。以下是使用 fs.writeFile 的真实示例
1赞 nponeccop 5/13/2019
是否有关于实现缓冲写入的生产质量库?npm
60赞 Mister P 12/16/2013 #4
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');
        })
    });
});

评论

2赞 Sean Glover 1/19/2015
这演示了如何使用较低级别的 FS 操作写入文件。例如,您可以保证文件何时完成对磁盘的写入并释放了文件描述符。
0赞 Manfred 2/10/2020
由于在此示例中,如果将偏移量设置为 '0' (= 第三个参数),因此此示例仅在所有内容都足够短以在单个写入调用中写入时才有效。fs.write()
11赞 Gunjan Patel 10/1/2014 #5

在这里,我们使用 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 是指您必须写入文件的内容及其长度 'content.length'。

35赞 Sérgio 11/8/2014 #6

我喜欢./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);

评论

0赞 Kai Feng Chew 12/19/2014
在哪里可以找到文件 helloworld.txt ?我在任何文件夹中都找不到它...谢谢。
0赞 Sérgio 12/20/2014
在运行脚本的文件夹中
0赞 Kai Feng Chew 12/20/2014
这很奇怪......我只是在任何地方都找不到它。它会被隐藏吗?再次感谢~
7赞 Kai Feng Chew 12/22/2014
我刚刚找到了它。使用此ROOT_APP_PATH = fs.realpathSync('.');控制台.log(ROOT_APP_PATH);获取我的文件写入位置。谢谢。
0赞 Amir 12/20/2018
@Sérgio:我们需要关闭 Writefile 吗?我正在调用另一个进程,并且我收到有关文件开始被其他进程使用的错误消息。
2赞 Christoper 5/4/2016 #7

您可以使用库easy-file-manager

首先从 npm 安装npm install easy-file-manager

上传和删除文件的示例

var filemanager = require('easy-file-manager')
var path = "/public"
var filename = "test.jpg"
var data; // buffered image

filemanager.upload(path,filename,data,function(err){
    if (err) console.log(err);
});

filemanager.remove(path,"aa,filename,function(isSuccess){
    if (err) console.log(err);
});

评论

2赞 Green 10/9/2016
This modules is created to save and remove files..不是答案。
11赞 Masoud Siahkali 10/23/2016 #8
 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");
                            });
                        }
                });

评论

0赞 Ravi Shanker Reddy 5/18/2017
您将数据写入“to.text”的位置?
0赞 Dan Dascalescu 10/23/2019
这个答案对多个已经存在的答案有什么补充?writeFile
6赞 KARTHIKEYAN.A 9/1/2017 #9

以下是如何从本地读取文件 csv 并将 csv 文件写入本地的示例。

var csvjson = require('csvjson'),
    fs = require('fs'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient,
    mongoDSN = 'mongodb://localhost:27017/test',
    collection;

function uploadcsvModule(){
    var data = fs.readFileSync( '/home/limitless/Downloads/orders_sample.csv', { encoding : 'utf8'});
    var importOptions = {
        delimiter : ',', // optional 
        quote     : '"' // optional 
    },ExportOptions = {
        delimiter   : ",",
        wrap        : false
    }
    var myobj = csvjson.toSchemaObject(data, importOptions)
    var exportArr = [], importArr = [];
    myobj.forEach(d=>{
        if(d.orderId==undefined || d.orderId=='') {
            exportArr.push(d)
        } else {
            importArr.push(d)
        }
    })
    var csv = csvjson.toCSV(exportArr, ExportOptions);
    MongoClient.connect(mongoDSN, function(error, db) {
        collection = db.collection("orders")
        collection.insertMany(importArr, function(err,result){
            fs.writeFile('/home/limitless/Downloads/orders_sample1.csv', csv, { encoding : 'utf8'});
            db.close();
        });            
    })
}

uploadcsvModule()

评论

1赞 Dan Dascalescu 10/23/2019
这引入了与问题无关的各种复杂情况(MongoClient、JSON 等)。
109赞 Moriarty 5/17/2018 #10

同步写入

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

fs = require('fs');

fs.writeFileSync("foo.txt", "bar");

异步写入

fs.writeFile(file, data[, options], callback)

fs = require('fs');

fs.writeFile('foo.txt', 'bar', (err) => { if (err) throw err; });

哪里

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

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

更新:async/await

fs = require('fs');
util = require('util');
writeFile = util.promisify(fs.writeFile);

fn = async () => { await writeFile('foo.txt', 'bar'); }

fn()

评论

0赞 parsecer 4/21/2023
如何同步追加到文件?
28赞 Astra Bear 5/28/2018 #11

我知道关于“写入”的问题,但从更一般的意义上讲,“追加”在某些情况下可能很有用,因为它很容易在循环中使用以将文本添加到文件(无论文件是否存在)。如果要添加行,请使用“\n”,例如:

const fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}

评论

3赞 Manfred 2/10/2020
由于它现在可用,我建议使用 代替 ,即 ,以避免不必要的副作用,特别是如果您使用的是更大的代码库。constvarconst fs = require('fs');
14赞 Oleksii Trekhleb 9/20/2018 #12

您可以使用 fs(文件系统)模块写入文件。

以下是如何执行此操作的示例:

const fs = require('fs');

const writeToFile = (fileName, callback) => {
  fs.open(fileName, 'wx', (error, fileDescriptor) => {
    if (!error && fileDescriptor) {
      // Do something with the file here ...
      fs.writeFile(fileDescriptor, newData, (error) => {
        if (!error) {
          fs.close(fileDescriptor, (error) => {
            if (!error) {
              callback(false);
            } else {
              callback('Error closing the file');
            }
          });
        } else {
          callback('Error writing to new file');
        }
      });
    } else {
      callback('Could not create new file, it may already exists');
    }
  });
};

您可能还希望通过使用 Promise 和 / 语句来摆脱此回调内部回调代码结构。这将使异步代码结构更加扁平化。为此,可以使用一个方便的 util.promisify(original) 函数。它允许我们从回调切换到承诺。请看下面函数的示例:asyncawaitfs

// Dependencies.
const util = require('util');
const fs = require('fs');

// Promisify "error-back" functions.
const fsOpen = util.promisify(fs.open);
const fsWrite = util.promisify(fs.writeFile);
const fsClose = util.promisify(fs.close);

// Now we may create 'async' function with 'await's.
async function doSomethingWithFile(fileName) {
  const fileDescriptor = await fsOpen(fileName, 'wx');

  // Do something with the file here...

  await fsWrite(fileDescriptor, newData);
  await fsClose(fileDescriptor);
}

评论

1赞 Zimano 8/29/2019
为什么这些片段而不是代码片段?无论如何,它们将永远无法在浏览器中运行。
0赞 Manfred 2/10/2020
@Zimano 据我了解,问题是关于nodejs的,所以不需要能够在浏览器中运行。
1赞 Zimano 2/11/2020
@Manfred 没错!我想你误解了我想说的话;拥有片段是没有意义的,因为它是 nodejs!
6赞 user9258013 12/23/2018 #13

fs.createWriteStream(path[,options])

options还可以包括一个选项,允许在文件开头之后的某个位置写入数据。修改文件而不是替换文件可能需要 模式而不是默认模式。编码可以是 Buffer 接受的任何一种编码。startflagsr+w

如果设置为 true(默认行为),否则文件描述符将自动关闭。如果为 false,则不会关闭文件描述符,即使存在错误也是如此。应用程序负责关闭它并确保没有文件描述符泄漏。autoClose'error''finish'autoClose

ReadStream 一样,如果指定了 WriteStream,则 WriteStream 将忽略该参数,并使用指定的文件描述符。这意味着不会发出任何事件。 应该是阻塞的;非阻塞 S 应传递给 Net。套接字fdpath'open'fdfd

如果是字符串,则指定编码。options

之后,阅读了这篇长文。您应该了解它是如何工作的。 因此,下面是 .createWriteStream()

/* The fs.createWriteStream() returns an (WritableStream {aka} internal.Writeable) and we want the encoding as 'utf'-8 */
/* The WriteableStream has the method write() */
fs.createWriteStream('out.txt', 'utf-8')
.write('hello world');

评论

0赞 Dan Dascalescu 10/23/2019
createWriteStream在此之前的多个回答中已经提到过。
-1赞 Mudassir 1/18/2019 #14

您可以通过以下代码示例在文件中写入:

var data = [{ 'test': '123', 'test2': 'Lorem Ipsem ' }];
fs.open(datapath + '/data/topplayers.json', 'wx', function (error, fileDescriptor) {
  if (!error && fileDescriptor) {
    var stringData = JSON.stringify(data);
    fs.writeFile(fileDescriptor, stringData, function (error) {
      if (!error) {
        fs.close(fileDescriptor, function (error) {
          if (!error) {
            callback(false);
          } else {
            callback('Error in close file');
          }
        });
      } else {
        callback('Error in writing file.');
      }
    });
  }
});

评论

1赞 Dan Dascalescu 10/23/2019
writeFile几年前,已经多次给出答案。这个答案增加了什么?
0赞 Michal 1/6/2020
另外,你为什么要打开文件?答案不应该是关于写文件吗?
17赞 Alireza 1/28/2019 #15

好的,这很简单,因为 Node 具有内置功能,它被称为 File System,基本上,NodeJS 文件系统模块......fs

因此,首先在服务器.js文件中需要它,如下所示:

var fs = require('fs');

fs很少有方法可以写到文件,但我的首选方法是使用 ,这会将内容附加到文件中,如果文件不存在,将创建一个,代码可能如下所示:appendFile

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});

评论

3赞 Tamer 3/28/2019
字符串中的单引号应转义。
43赞 TrevTheDev 4/28/2019 #16

提供的答案已经过时,一种较新的方法是:

const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')

有关详细信息,请参阅此处的文档

评论

0赞 TrevTheDev 4/30/2019
@jgraup:您使用的是最新版本的 Node 吗?
0赞 jgraup 4/30/2019
节点v10.15.0
1赞 TrevTheDev 4/30/2019
@jpraup - 最新的是节点 12。
9赞 Zimano 8/29/2019
封闭函数必须是异步的,否则这将不起作用。
2赞 wintercounter 4/26/2020
@Zimano Node 已经支持顶级 await,则不需要异步包装器。
14赞 Predrag Davidovic 6/18/2020 #17

您可以写入包含流的文件。

就这样做:

const fs = require('fs');

const stream = fs.createWriteStream('./test.txt');
stream.write("Example text");
6赞 subhadip pahari 9/1/2020 #18

要点1:

如果要将某些内容写入文件。 意味着:它将删除文件中已保存的任何内容并写入新内容。使用 fs.promises.writeFile()

要点2:

如果要将某些内容附加到文件中。 表示:它不会删除文件中已保存的任何内容,而是在文件内容中附加新项目。然后首先读取文件,然后将内容添加到可读值中,然后将其写入文件。所以使用 fs.promises.readFile 和 fs.promises.writeFile()


示例 1:我想在我的 JSON 文件中编写一个 JSON 对象。

const fs = require('fs');
const data = {table:[{id: 1, name: 'my name'}]}
const file_path = './my_data.json'
writeFile(file_path, data)
async function writeFile(filename, writedata) {
  try {
    await fs.promises.writeFile(filename, JSON.stringify(writedata, null, 4), 'utf8');
    console.log('data is written successfully in the file')
  }
  catch (err) {
    console.log('not able to write data in the file ')
  }
}

示例2: 如果要将数据追加到 JSON 文件。 您希望将数据 {id:1, name:'my name'} 添加到同一文件夹根目录上的文件my_data.json。只需调用append_data(file_path,数据)函数即可。

如果文件存在,它将在 JSON 文件中附加数据。或者它将创建文件并将数据添加到其中。

const fs = require('fs');
const data = {id: 2, name: 'your name'}
const file_path = './my_data.json'
append_data(file_path, data)

async function append_data(filename, data) {

  if (fs.existsSync(filename)) {
    var read_data = await readFile(filename)
    if (read_data == false) {
      console.log('not able to read file')
    } else {
      read_data.table.push(data)  //data must have the table array in it like example 1
      var dataWrittenStatus = await writeFile(filename, read_data)
      if (dataWrittenStatus == true) {
        console.log('data added successfully')
      } else {
        console.log('data adding failed')
      }
    }
  }
}

async function readFile(filePath) {
  try {
    const data = await fs.promises.readFile(filePath, 'utf8')
    return JSON.parse(data)
  }
  catch (err) {
    return false;
  }
}

async function writeFile(filename, writedata) {
  try {
    await fs.promises.writeFile(filename, JSON.stringify(writedata, null, 4), 'utf8');
    return true
  }
  catch (err) {
    return false
  }
}