nodejs 数据读写详解

P1 缓存 Buffer

1. 创建缓存

var buf = new Buffer(10);

var buf = new Buffer([10, 20, 30, 40, 50]);

//支持"ascii", "utf8", "utf16le", "ucs2", "base64" or "hex"
var buf = new Buffer("Simply Easy Learning", "utf-8");

2. 写缓存 buf.write(string[, offset][, length][, encoding])

  • string:待写入缓存的数据
  • offset:写入缓存的偏移量
  • length:写入数据的数量
  • encoding:编码模式,默认为utf8
buf = new Buffer(256);
len = buf.write("Simply Easy Learning");

console.log("Octets written : "+  len);
When the above program is executed, it produces the following result −

Octets written : 20

3. 读缓存 buf.toString([encoding][, start][, end])

  • encoding:编码模式,默认为utf8
  • start:开始读取的位置
  • end:结束读取的位置
buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}
console.log( buf.toString('ascii'));       // outputs: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   // outputs: abcde
console.log( buf.toString('utf8',0,5));    // outputs: abcde
console.log( buf.toString(undefined,0,5)); // encoding defaults to 'utf8', outputs abcde

//运行输出
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde

4. 转换成JSON buf.toJSON()

  • encoding:编码模式,默认为utf8
  • start:开始读取的位置
  • end:结束读取的位置
var buf = new Buffer('Simply Easy Learning');
var json = buf.toJSON(buf);
console.log(json);

//运行输出
[ 83, 105, 109, 112, 108, 121, 32, 69, 97, 115, 121, 32, 76, 101, 97, 114, 110, 105, 110,
   103 ]

5. 合并缓存 Buffer.concat(list[, totalLength])

  • list:缓存的数组
  • totalLength:合并缓冲的总长度
var buffer1 = new Buffer('TutorialsPoint ');
var buffer2 = new Buffer('Simply Easy Learning');
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 content: " + buffer3.toString());

//运行输出
buffer3 content: TutorialsPoint Simply Easy Learning

6. 比较缓存 buf.compare(otherBuffer);

  • otherBuffer:待比较的缓存
var buffer1 = new Buffer('ABC');
var buffer2 = new Buffer('ABCD');
var result = buffer1.compare(buffer2);

if(result < 0) {
   console.log(buffer1 +" comes before " + buffer2);
}else if(result == 0){
   console.log(buffer1 +" is same as " + buffer2);
}else {
   console.log(buffer1 +" comes after " + buffer2);
}

//运行输出
ABC comes before ABCD

7. 拷贝缓存 buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])

  • targetBuffer:目标缓存
  • targetStart:目标的起始位置
  • sourceStart: 源的起始位置
  • sourceEnd:源的结束位置
var buffer1 = new Buffer('ABC');

//copy a buffer
var buffer2 = new Buffer(3);
buffer1.copy(buffer2);
console.log("buffer2 content: " + buffer2.toString());

//运行输出
buffer2 content: ABC

8. 分割缓存 buf.slice([start][, end])

  • start:开始位置
  • end:结束位置
var buffer1 = new Buffer('TutorialsPoint');
//slicing a buffer
var buffer2 = buffer1.slice(0,9);
console.log("buffer2 content: " + buffer2.toString());));

//运行输出
buffer2 content: Tutorials

9. 缓存长度 buf.length;

  • start:开始位置
  • end:结束位置
var buffer = new Buffer('TutorialsPoint');
//length of the buffer
console.log("buffer length: " + buffer.length);

//运行输出
buffer length: 14

P2 文件系统 FileSystem

1. 同步读取 readFileSync

//没有声明encoding时返回二进制数据
var fs = require('fs');
var data = fs.readFileSync('input.txt');
console.log("Synchronous read: " + data.toString());

//声明encoding时返回字符串
var fs = require('fs');
var data = fs.readFileSync('input.txt',  { encoding: 'utf-8' });
console.log("Synchronous read: " + data.toString());

//使用try..catch处理异常
try{
    var err = fs.readFileSync('noneExist.txt');
}catch(err){
    console.log(err.message);  // 输出no such file or directory 'noneExist.txt'
}

2. 异步读取 readFile

//没有声明encoding时返回二进制数据
fs.readFile('input.txt', function(err, data){
    if (err) {
      return console.error(err);
   }
   console.log("Asynchronous read: " + data.toString());
});

//声明encoding时返回字符串
fs.readFile('input.txt', {encoding: 'utf-8'}, function(err, data){
    if (err) {
      return console.error(err);
   }
   console.log("Asynchronous read: " + data.toString());
});

3. 打开文件 fs.open(path, flags[, mode], callback)

Flag Description
r Open file for reading. An exception occurs if the file does not exist.
r+ Open file for reading and writing. An exception occurs if the file does not exist.
rs Open file for reading in synchronous mode.
rs+ Open file for reading and writing, asking the OS to open it synchronously. See notes for 'rs' about using this with caution.
w Open file for writing. The file is created (if it does not exist) or truncated (if it exists).
wx Like 'w' but fails if the path exists.
w+ Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).
wx+ Like 'w+' but fails if path exists.
a Open file for appending. The file is created if it does not exist.
ax Like 'a' but fails if the path exists.
a+ Open file for reading and appending. The file is created if it does not exist.
ax+ Like 'a+' but fails if the the path exists.
// 异步打开文件
var fs = require("fs");
console.log("Going to open file!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
  console.log("File opened successfully!");     
});

4. 取文件信息 fs.stat(path, callback)

Method Description
stats.isFile() Returns true if file type of a simple file.
stats.isDirectory() Returns true if file type of a directory.
stats.isBlockDevice() Returns true if file type of a block device.
stats.isCharacterDevice() Returns true if file type of a character device.
stats.isSymbolicLink() Returns true if file type of a symbolic link.
stats.isFIFO() Returns true if file type of a FIFO.
stats.isSocket() Returns true if file type of asocket.
var fs = require("fs");
console.log("Going to get file info!");
fs.stat('input.txt', function (err, stats) {
   if (err) {
       return console.error(err);
   }
   console.log(stats);
   console.log("Got file info successfully!");

   // Check file type
   console.log("isFile ? " + stats.isFile());
   console.log("isDirectory ? " + stats.isDirectory());    
});

运行程序后输出

Going to get file info!
{ 
   dev: 1792,
   mode: 33188,
   nlink: 1,
   uid: 48,
   gid: 48,
   rdev: 0,
   blksize: 4096,
   ino: 4318127,
   size: 97,
   blocks: 8,
   atime: Sun Mar 22 2015 13:40:00 GMT-0500 (CDT),
   mtime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT),
   ctime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT) 
}
Got file info successfully!
isFile ? true
isDirectory ? false

5. 写文件 fs.writeFile(filename, data[, options], callback)

  • path:文件名称(包括路径)
  • data:字符串(String)或者数据缓存(Buffer)
  • options:可选项,可以设置 encoding , mode, flag; 默认encoding是 utf8, mode是八进制 0666,flag是 w
  • callback:包括一个错误返回参数的回调函数
var fs = require("fs");

console.log("Going to write into existing file");
fs.writeFile('input.txt', 'Simply Easy Learning!',  function(err) {
   if (err) {
      return console.error(err);
   }
   
   console.log("Data written successfully!");
   console.log("Read newly written data");
   fs.readFile('input.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("Asynchronous read: " + data.toString());
   });
});

//运行后输出
Going to write into existing file
Data written successfully!
Read newly written data
Asynchronous read: Simply Easy Learning!

6. 读文件 fs.read(fd, buffer, offset, length, position, callback)

  • fd:读取成功后返回的文件句柄
  • buffer:读取后的数据会写入到该缓冲区
  • offset:写入缓冲区的偏移地址
  • length:读取的数据数量
  • position:读取的位置,如果为 null,则从当前位置读取
  • callback:回调函数
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + " bytes read");
      
      // Print only read bytes to avoid junk.
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});

//运行后输出
Going to open an existing file
File opened successfully!
Going to read the file
97 bytes read
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

7. 关闭文件 fs.close(fd, callback)

  • fd:读取成功后返回的文件句柄
  • callback:回调函数
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }

      // Print only read bytes to avoid junk.
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }

      // Close the opened file.
      fs.close(fd, function(err){
         if (err){
            console.log(err);
         } 
         console.log("File closed successfully.");
      });
   });
});

//运行后输出
Going to open an existing file
File opened successfully!
Going to read the file
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

File closed successfully.

8. 删除文件 fs.unlink(path, callback)

  • path:文件名称(包括路径)
  • callback:回调函数
var fs = require("fs");

console.log("Going to delete an existing file");
fs.unlink('input.txt', function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("File deleted successfully!");
});

9. 建立目录 fs.mkdir(path[, mode], callback)

  • path:文件名称(包括路径)
  • mode:目录权限,默认值 0777
  • callback:回调函数
var fs = require("fs");

console.log("Going to create directory /tmp/test");
fs.mkdir('/tmp/test',function(err){
   if (err) {
      return console.error(err);
   }
   console.log("Directory created successfully!");
});

10. 读取目录 fs.readdir(path, callback)

  • path:文件名称(包括路径)
  • callback:回调函数
var fs = require("fs");

console.log("Going to read directory /tmp");
fs.readdir("/tmp/",function(err, files){
   if (err) {
      return console.error(err);
   }
   files.forEach( function (file){
      console.log( file );
   });
});

11. 删除目录 fs.rmdir(path, callback)

  • path:文件名称(包括路径)
  • callback:回调函数
var fs = require("fs");

console.log("Going to delete directory /tmp/test");
fs.rmdir("/tmp/test",function(err){
   if (err) {
      return console.error(err);
   }
   console.log("Going to read directory /tmp");
   
   fs.readdir("/tmp/",function(err, files){
      if (err) {
         return console.error(err);
      }
      files.forEach( function (file){
         console.log( file );
      });
   });
});

P3 数据流 Streams

流是 unix 管道,可以从数据源读取数据,然后流向另一个目的地。nodejs有4种数据流:

  • Readable:可读流
  • Writable:可写流 − Stream which is used for write operation.
  • Duplex:读写流
  • Transform:转换流,输出数据根据输入数据计算

1. 读取流

假设有文本 input.txt,内容如下:

Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

编写main.js如下:

var fs = require("fs");
var data = '';

//readableStream.setEncoding('utf8'); 可以设置编码,回调函数中的 chunk 就会是字符串

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Set the encoding to be utf8. 
readerStream.setEncoding('UTF8');

// Handle stream events --> data, end, and error
readerStream.on('data', function(chunk) {
   data += chunk;
});

readerStream.on('end',function(){
   console.log(data);
});

readerStream.on('error', function(err){
   console.log(err.stack);
});
console.log("Program Ended");

//运行输出
Program Ended
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

2. 改写流

var fs = require("fs");
var data = 'Simply Easy Learning';

// 创建可写流
var writerStream = fs.createWriteStream('output.txt');

// 以utf8的编码写入数据
writerStream.write(data,'UTF8');

// 标记文件结束
// 当 end() 被调用时,所有数据会被写入,然后流会触发一个 finish 事件。
// 调用 end() 之后就不能再往可写流中写入数据
writerStream.end();

// 处理结束事件和错误事件
writerStream.on('finish', function() {
    console.log("Write completed.");
});

writerStream.on('error', function(err){
   console.log(err.stack);
});

console.log("Program Ended"); and easy way!!!!!

运行结束后output.txt的内容为 Simply Easy Learning

3. 管道 Piping

管道是一个很棒的机制,你不需要自己管理流的状态就可以从数据源中读取数据,然后写入到目的地中。

将input.txt的数据写入到output.txt

var fs = require("fs");
var readerStream = fs.createReadStream('input.txt');
var writerStream = fs.createWriteStream('output.txt');
readerStream.pipe(writerStream);
console.log("Program Ended");

4. 管道 Chaining

链接可以将输出流作为下一个函数的输入

将压缩文件input.txt.gz解压后的内容放到新文件output.txt

var fs = require('fs');
var zlib = require('zlib');

fs.createReadStream('input.txt.gz')
 .pipe(zlib.createGunzip())
 .pipe(fs.createWriteStream('output.txt'));

 console.log("File Compressed.");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容

  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 6,312评论 0 6
  • 文件系统模块是一个封装了标准的 POSIX 文件 I/O 操作的集合。通过require('fs')使用这个模块。...
    保川阅读 774评论 0 0
  • //公共引用 varfs =require('fs'), path =require('path'); 1、读取文...
    才気莮孒阅读 827评论 0 1
  • Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScr...
    FTOLsXD阅读 530评论 0 2
  • 本文的主要内容是对nodejs提供的一些重要模块,结合官方API进行介绍,遇到精彩的文章,我会附在文中并标明了出处...
    艾伦先生阅读 940评论 0 3