我一直试图找到一种方法,在使用Node.js时向文件写入,但没有成功。我怎样才能做到这一点呢?
在文件系统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!");
});
目前,有三种方法来写一个文件。
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年6月2日公布的稳定版)中,现在支持两个函数。
cork()
和
uncork()
。似乎这些函数最终将允许你缓冲/冲刷写入调用。
例如,在Java中,有一些类提供了缓冲流(BufferedOutputStream
, BufferedWriter
...)。如果你写了三个字节,这些字节将被存储在缓冲区(内存)中,而不是仅仅为三个字节做一个I/O调用。当缓冲区满时,内容会被刷新并保存到磁盘。这就提高了性能。
我没有发现什么,只是记住了磁盘访问应该如何进行。
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.writeFileSync(file, data[, options]) fs.writeFileSync(file, data[, options])
fs = require('fs');
fs.writeFileSync("synchronous.txt", "synchronous write!")
异步写入
fs.writeFile(file, data[, options], callback) fs.writeFile(file, data[, options], callback)
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)docs。
1:
我喜欢[./articles/file-system的索引][1]。
它对我来说很有用。
也可以参考[如何在node.js中写文件?][2]。
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!
[1]: https://docs.nodejitsu.com/articles/file-system [2]: https://docs.nodejitsu.com/articles/file-system/how-to-write-files-in-nodejs
更新:在Linux中,node写在当前目录,似乎在其他一些地方不写,所以我加了这句话以备不时之需。
由于在Linux中node写在当前目录下,似乎在其他一些人不't,所以我添加这个注释,以备不时之需。
使用这个ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);
来获取文件的写入位置。
我知道问题问的是"写"。 但从更广泛的意义上讲,"append" 在某些情况下可能是有用的,因为它很容易在循环中添加文本到一个文件中(无论文件是否存在)。 使用"追加"。 如果您想添加行,例如
var fs = require('fs');
for (var i=0; i<10; i++){
fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
提供的答案已经过时,更新的方法是。
const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')
OK,这很简单,因为Node有内置的功能,它叫做fs
,代表文件系统,基本上就是NodeJS文件系统模块......所以首先在你的server.js文件中需要它。
所以首先在你的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!');
});
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");
});
}
});
您可以使用[fs]1模块向文件写入。
下面是一个例子,说明你可以如何做。
-- begin snippet: js hide: false console: truefalse -->
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.promify(original)][2]函数可能会被利用。
它允许我们从回调切换到承诺。
看看下面的带有fs
函数的例子。
<!--开始片段。 js hide: false console: true babel.false --> -- begin snippet: js hide: false console: true false -->
// 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]: https://nodejs.org/api/fs.html [2]: https://nodejs.org/api/util.html#util_util_promisify_original
这里我们使用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'。
下面是如何从本地读取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()
你可以通过下面的代码示例写进文件。
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));
fs.writeFile(fileDescriptor, stringData, function (error) {
if (!error) {
fs.close(fileDescriptor, function (error) {
if (!error) {
callback(false);
} else {
callback('关闭文件时出错');
}
});
} else {
callback('文件写入错误。')。
}
});
}
});
options
还可以包括start
选项,允许在文件开头的某个位置写入数据。 修改文件而不是替换文件可能需要flags
模式r+
而不是默认模式w
。 编码可以是Buffer所接受的任何一种。
>.如果autoClose'是一个 "flags "模式,而不是默认的 "w "模式,那么这个 "flags "模式可以是[Buffer]()所接受的任何一种编码。 如果在
'error'或
'finish'时
autoClose被设置为true(默认行为),文件描述符将被自动关闭。 如果
autoClose`为false,那么即使出现错误,文件描述符也不会被关闭。
关闭它并确保没有文件描述符泄漏是应用程序的责任。
和 ReadStream一样,如果指定了
fd
,WriteStream将忽略path
参数,并将使用指定的文件描述符。 这意味着不会发出'open'
事件。fd
应该是阻塞的。 非阻塞的fd
应该传递给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');
你可以使用库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);
});