在Node.js中编写文件

Gjo*_*gji 1538 javascript file fs node.js express

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

Bri*_*nna 2328

文件系统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!");
}); 
Run Code Online (Sandbox Code Playgroud)

  • 另请注意,您可以使用fs.writeFileSync(...)同步完成相同的操作. (119认同)
  • 实际上,@ DenysVitali,问题是jane应该不能将任何文件写入`/ home/...`.通常该目录是755 root:wheel(或其他).如果node想要将文件写为jane,那么写入`/ home/jane/test.txt`会更容易.将`/ home`改为比755更宽松的东西是一个巨大的错误. (36认同)
  • 我已经使用Node测试了这个脚本,我尝试将文件路径更改为"/ home /",但是我收到以下错误:`{[错误:EACCES,打开'/home/test.txt']错误:3 ,代码:'EACCES',路径:'/ home/test.txt'}`我如何修改这个脚本,使它在`/ tmp`之外工作? (23认同)
  • @JaneAvriette好吧,既然他想将文件保存在`/ home`目录中,我建议chmod它.我知道它可能会产生安全问题.但是,如果用户想要保存,那就是解决方案.PS:我同意你所说的(: (7认同)
  • 也许它有点旧,但是@AndersonGreen,你需要以root用户身份或chmod/home运行节点,以允许对当前节点进程所有者的R/W权限(你的用户名很难),这样你就可以编写文件了 (6认同)
  • 完成后是否需要`fs.close()`? (4认同)

Gab*_*mas 514

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

  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")
Run Code Online (Sandbox Code Playgroud)

你在做:

fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Fre*_*son 246

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

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

  • 传递给stream.once的回调的'fd'变量是什么? (14认同)
  • 我什么时候关闭流?为什么这种非阻塞?只是好奇,我正在尝试写入日志文件. (3认同)
  • @ScottDavidTesler 文件描述符,因此您可以在完成后关闭流。 (2认同)
  • 这个示例给我留下了一个空的“my_file.txt”和 WriteStream 对象的转储。 (2认同)

Mor*_*rty 51

同步写入

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

fs = require('fs');

fs.writeFileSync("synchronous.txt", "synchronous write!")
Run Code Online (Sandbox Code Playgroud)

异步写入

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

fs = require('fs');

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

哪里

file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>
Run Code Online (Sandbox Code Playgroud)

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


Mis*_*r P 50

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

  • 这演示了如何使用较低级别的fs操作写入文件。例如,您可以保证文件何时完成写入磁盘并释放文件描述符。 (2认同)

Sér*_*gio 29

我喜欢./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');
});
Run Code Online (Sandbox Code Playgroud)

helloworld.txt的内容:

Hello World!
Run Code Online (Sandbox Code Playgroud)

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

  • 我刚发现它.使用此__ROOT_APP_PATH__ = fs.realpathSync('.'); 的console.log(__ ROOT_APP_PATH__); 得到我写的文件的位置.谢谢. (6认同)

Tre*_*Dev 16

提供的答案已过时,执行此操作的新方法是:

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

在此处查看文档以获取更多信息

  • 封闭函数必须是异步的,否则将不起作用。 (9认同)
  • @Zimano Node 已经支持顶级等待,您不需要异步包装器。 (2认同)

Ast*_*ear 14

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

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

  • 由于它现在可用,我建议使用 `const` 而不是 `var`,即 `const fs = require('fs');`,以避免不必要的副作用,特别是如果您正在使用更大的代码库。 (3认同)

Pre*_*vic 14

您可以使用流写入文件。

只需这样做:

const fs = require('fs');

const stream = fs.createWriteStream('./test.txt');
stream.write("Example text");
Run Code Online (Sandbox Code Playgroud)


Gun*_*tel 11

在这里,我们使用 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');
            })
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

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


Mas*_*ali 8

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

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

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


Ali*_*eza 8

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

所以首先在您的server.js文件中要求它是这样的:

var fs = require('fs');
Run Code Online (Sandbox Code Playgroud)

fs有几种方法可以写入文件,但是我的首选方式是使用appendFile,这会将东西添加到文件中,如果文件不存在,将创建一个,代码可能如下所示:

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

  • 字符串中的单引号应转义。 (3认同)

KAR*_*N.A 6

这是如何从本地读取文件 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()
Run Code Online (Sandbox Code Playgroud)


Ole*_*leb 6

您可以使用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');
    }
  });
};
Run Code Online (Sandbox Code Playgroud)

您可能还想通过使用Promisesasync/ await语句来摆脱这种内部回调函数的代码结构。这将使异步代码结构更加平坦。为此,可以使用方便的util.promisify(原始)函数。它使我们能够从回调切换到承诺。看一下fs下面的函数示例:

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


小智 6

fs.createWriteStream(path[,options])

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

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

ReadStream一样,如果fd指定,WriteStream将忽略该path参数并使用指定的文件描述符。这意味着不会'open'发出任何事件。fd应该是阻塞的;非阻塞fds 应该传递给net.Socket

如果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');
Run Code Online (Sandbox Code Playgroud)


sub*_*ari 6

第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 ')
  }
}
Run Code Online (Sandbox Code Playgroud)

example2 :如果要将数据附加到 JSON 文件。您想要将数据{id:1, name:'my name'}添加到同一文件夹根目录下的my_data.json文件中。只需调用append_data(file_path,data)函数即可。

如果文件存在,它将在 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
  }
}
Run Code Online (Sandbox Code Playgroud)