nodejs文档里api一大堆,该怎么选择呢?我这里挑选了几个常用的出来。
fs 模块提供了一些 API,用于以一种类似标准 POSIX 函数的方式与文件系统进行交互。
const fs = require('fs');
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('成功删除 /tmp/hello');
});
const fs = require('fs');
try {
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// handle the error
}
const fs = require("fs");
fs.readFile("./1.txt",(err,data)=>{
console.log(data);
})
我们怎么知道它正确读取到了呢?一堆16进制的buffer.
readFile接收三个参数,必选参数:路径,可选参数:编码,必选参数:回调函数。
const fs = require("fs");
fs.readFile("./1.txt","utf-8",(err,data)=>{
console.log(data);
})
const fs = require("fs");
const fn = async () => {
const data = await new Promise((resovle,reject) => {
fs.readFile('1.txt','utf-8',(err,data) => {
if(err) return reject(err)
resovle(data)
})
})
console.log(data,111);
}
console.log(1);
console.log(fn(),222);
console.log(2);
显然异步读取数据不能这样做,人家本身就是异步的,你还拿异步的去取,肯定靠天吃饭啦。
想要准确的拿数据,还是得遵守async函数的规则,乖乖在它的怀抱下等待。
const fs = require("fs");
console.log(1);
const data = fs.readFileSync('1.txt','utf-8')
console.log(data);
console.log(2);
很愉快的读取到数据,因为是同步,所以后面的代码必须等待前面读取文件成功才能继续执行。如果文件非常大,所以还是乖乖异步吧!
如果你把1.txt删了或者路径下没有这个文件的话会自动创建文件
const fs = require("fs");
console.log(1);
const data = '写入测试文字'
fs.writeFile('1.txt',data,res=>{
console.log(res,11111);
})
console.log(2);
但是如果仅是这样的话,会把原来的文字覆盖。
const fs = require("fs");
console.log(1);
const data = '写入测试文字'
fs.writeFileSync('1.txt', data, res => {
console.log(res, 11111);
})
console.log(2);
因为这个写函数如果没有对应文件会自己新建,所以想报错还真的很难!暂时没有错误示例!
fs.open(path, flags[, mode], callback)
四个参数,mode是默认的:
|
|
|
Default: 0o666
‘r’ - 以读取模式打开文件。如果文件不存在则发生异常。
‘r+’ - 以读写模式打开文件。如果文件不存在则发生异常。
‘rs+’ - 以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存。
这对 NFS 挂载模式下打开文件很有用,因为它可以让你跳过潜在的旧本地缓存。 它对 I/O 的性能有明显的影响,所以除非需要,否则不要使用此标志。
注意,这不会使 fs.open() 进入同步阻塞调用。 如果那是你想要的,则应该使用 fs.openSync()。
‘w’ - 以写入模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
‘wx’ - 类似 ‘w’,但如果 path 存在,则失败。
‘w+’ - 以读写模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
‘wx+’ - 类似 ‘w+’,但如果 path 存在,则失败。
‘a’ - 以追加模式打开文件。如果文件不存在,则会被创建。
‘ax’ - 类似于 ‘a’,但如果 path 存在,则失败。
‘a+’ - 以读取和追加模式打开文件。如果文件不存在,则会被创建。
‘ax+’ - 类似于 ‘a+’,但如果 path 存在,则失败。
特有的标志 ‘x’(在 open(2) 中的 O_EXCL 标志)确保 path 是新创建的。 在 POSIX 操作系统中,path 会被视为存在,即使是一个链接到一个不存在的文件的符号。 该特有的标志有可能在网络文件系统中无法使用。
flags 也可以是一个数字,[open(2)] 文档中有描述; 常用的常量可从 fs.constants 获取。 在 Windows 系统中,标志会被转换为与它等同的替代者,例如,O_WRONLY 转换为 FILE_GENERIC_WRITE、或 O_EXCL|O_CREAT 转换为 CREATE_NEW,通过 CreateFileW 接受。
在 Linux 中,当文件以追加模式打开时,定位的写入不起作用。 内核会忽略位置参数,并总是附加数据到文件的末尾。
失败就不说了,读取成功后,fd将是读取文件中read方法的第一个参数,这个参数代表指定的文件。
注意:fs.open() 某些标志的行为是与平台相关的。 因此,在 macOS 和 Linux 下用 ‘a+’ 标志打开一个目录(见下面的例子),会返回一个错误。 与此相反,在 Windows 和 FreeBSD,则会返回一个文件描述符。
// macOS 与 Linux
fs.open('' , 'a+', (err, fd) => {
// => [Error: EISDIR: illegal operation on a directory, open ]
});
// Windows 与 FreeBSD
fs.open('' , 'a+', (err, fd) => {
// => null,
});
|
从 fd 指定的文件中读取数据。
buffer 是数据将被写入到的 buffer。
offset 是 buffer 中开始写入的偏移量。
length 是一个整数,指定要读取的字节数。
position 指定从文件中开始读取的位置。 如果 position 为 null,则数据从当前文件读取位置开始读取,且文件读取位置会被更新。 如果 position 为一个整数,则文件读取位置保持不变。
回调有三个参数 (err, bytesRead, buffer)。
如果调用该方法的 util.promisify() 版本,将会返回一个包含 bytesRead 和 buffer 属性的 Promise。
var fs = require('fs');
fs.open('./1.txt', 'r', function (err, fd) {
if(err) throw err
//buf根据你的需要设定每次的读取长度
var buf = new Buffer.alloc(225);
//读取fd文件内容到buf缓存区,如果position设置为null就会从最开始的地方开始读
fs.read(fd, buf, 0, 20, null, function (err, bytesRead, buffer) {
console.log(buf.slice(0, bytesRead).toString());
console.log(buf);
});
});
|
写入 buffer 到 fd 指定的文件。
offset 决定 buffer 中被写入的部分,length 是一个整数,指定要写入的字节数。
position 指向从文件开始写入数据的位置的偏移量。 如果 typeof position !== ‘number’,则数据从当前位置写入。详见 pwrite(2)。
回调有三个参数 (err, bytesWritten, buffer),其中 bytesWritten 指定从 buffer 写入了多少字节。
如果以 util.promisify() 的形式调用该方法,则会返回包含 bytesWritten 和 buffer 属性的 Promise 的对象。
注意,多次对同一文件使用 fs.write 且不等待回调,是不安全的。 对于这种情况,强烈推荐使用 fs.createWriteStream。
在 Linux 上,当文件以追加模式打开时,指定位置的写入是不起作用的。 内核会忽略位置参数,并总是将数据追加到文件的末尾。
var fs = require('fs');
fs.open('./1.txt', 'r+', function (err, fd) {
if(err) throw err
fs.write(fd, '文件追加字符测试', 20, 'utf-8', (err, written, buffer)=>{
console.log(err);
console.log(buffer);
})
});
写入后的结果,写入位置20,打印err,空,打印buffer,刚才写入的字符串!
const fs = require("fs");
console.log(111111);
const read = fs.createReadStream('1.txt')
read.setEncoding('utf-8')
read.resume();//让文件流开始'流'动起来
read.on('data',data =>{//监听读取的数据,如果打印data就是文件的内容
console.log('正在读');
})
read.on('end', () => { //监听状态
console.log('文件读取结束');
})
console.log(222222);
我这里准备了2万+行的数据,监听的data打印了多少次就说明被流监听了多少次,期间就可以使用多少次这个数据,用于一些超大型的数据读取还是非常有效的。
写入流
const fs = require("fs");
console.log(111111);
const read = fs.createReadStream('1.txt')
read.setEncoding('utf-8')
read.resume();//让文件流开始'流'动起来
read.on('data',data =>{
console.log('正在读');
})
read.on('end', () => { //监听状态
console.log('文件读取结束');
})
console.log(222222);
console.log(333333);
const write = fs.createWriteStream('2.txt')
read.pipe(write) //pipe就是那根水管,抽向2.txt
console.log(444444);
如果你自己测试的时候看着2.txt的行数在飞涨,会更加直观!