我一直在尝试找到一种在使用 Node.js 时写入文件的方法,但没有成功。我怎样才能做到这一点?
File System 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!');
目前有三种写文件的方法:
fs.write(fd, buffer, offset, length, position, callback) 需要等待回调确保缓冲区写入磁盘。它没有缓冲。 fs.writeFile(filename, data, [encoding], callback) 所有数据必须同时存储;您无法执行顺序写入。 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 中有一些提供缓冲流的类(BufferedOutputStream
、BufferedWriter
...)。如果您写入三个字节,这些字节将存储在缓冲区(内存)中,而不是只为三个字节执行 I/O 调用。当缓冲区已满时,内容将被刷新并保存到磁盘。这提高了性能。
我没有发现任何东西,只是记住应该如何进行磁盘访问。
cork()
和 uncork()
的示例?
npm
实现缓冲写入的生产质量库?
你当然可以让它更高级一点。非阻塞,写点点滴滴,不一次写整个文件:
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();
});
同步写入
fs.writeFileSync(文件,数据[,选项])
fs = require('fs');
fs.writeFileSync("foo.txt", "bar");
异步写入
fs.writeFile(文件,数据[,选项],回调)
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) docs。
更新:异步/等待
fs = require('fs');
util = require('util');
writeFile = util.promisify(fs.writeFile);
fn = async () => { await writeFile('foo.txt', 'bar'); }
fn()
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');
})
});
});
fs.write()
的第三个参数),则此示例仅在所有内容都足够短以在单个写入调用中写入时才有效。
提供的答案已过时,更新的方法是:
const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')
see documents here for more info
v10.15.0
我喜欢Index of ./articles/file-system。
它对我有用。
另请参阅How do I write files in 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);
来获取文件的写入位置。
我知道关于“写入”的问题,但在更一般的意义上,“附加”在某些情况下可能很有用,因为它很容易在循环中使用以向文件添加文本(无论文件是否存在)。如果要添加行,请使用“\n”,例如:
var fs = require('fs');
for (var i=0; i<10; i++){
fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
const
而不是 var
,即 const fs = require('fs');
,以避免不必要的副作用,尤其是在您使用更大的代码库时。
好的,这很简单,因为 Node 具有内置功能,它被称为 fs
,代表 File System,基本上,NodeJS 文件系统模块...
所以首先在你的 server.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!');
});
您可以使用 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');
}
});
};
您可能还想通过使用 Promises 和 async
/await
语句来摆脱这种回调内部回调代码结构。这将使异步代码结构更加平坦。为此,可以使用一个方便的 util.promisify(original) 函数。它允许我们从回调切换到承诺。看看下面的 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);
}
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");
});
}
});
writeFile
的多个答案有何补充?
在这里,我们使用 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”。
您可以使用流写入文件。
这样做:
const fs = require('fs');
const stream = fs.createWriteStream('./test.txt');
stream.write("Example text");
这是如何从本地读取文件 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()
fs.createWriteStream(path[,options]) 选项还可能包含一个开始选项,以允许在文件开头之后的某个位置写入数据。修改文件而不是替换它可能需要标志模式 r+ 而不是默认模式 w。编码可以是 Buffer 接受的任何一种。如果在“错误”或“完成”时将 autoClose 设置为 true(默认行为),则文件描述符将自动关闭。如果 autoClose 为 false,则即使出现错误,文件描述符也不会关闭。关闭它并确保没有文件描述符泄漏是应用程序的责任。与 ReadStream 一样,如果指定了 fd,WriteStream 将忽略路径参数并使用指定的文件描述符。这意味着不会发出“打开”事件。 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');
第 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 , 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
}
}
您可以使用库 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);
});
This modules is created to save and remove files.
。不是答案。
您可以通过以下代码示例写入文件:
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.');
}
});
}
});
writeFile
已多次作为答案给出。这个答案增加了什么?
{ [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' }
如何修改此脚本以使其在/tmp
之外工作?/home/...
。通常该目录是 755 root:wheel (或其他)。如果节点想以 jane 的身份写入文件,那么写入/home/jane/test.txt
会更容易。将/home
更改为比 755 更宽松的内容是一个巨大的错误。/home
目录中,所以我建议对它进行 chmod。我知道它可能会产生安全问题。但是,如果用户想在那里保存,那就是解决方案。 PS:我同意你说的(: