天天看點

Node.js-fs讀寫檔案API檔案的寫入讀取檔案流式檔案的寫入 —— 推薦流式檔案的讀取

檔案系統簡單來說就是通過Node來作業系統中的檔案

使用檔案系統,需要先引入fs子產品,fs是核心子產品,直接引入不需要下載下傳

異步和同步

Node.js 檔案系統(fs 子產品)子產品中的方法均有異步和同步版本,例如讀取檔案内容的函數有異步的 fs.readFile() 和同步的 fs.readFileSync()。

異步的方法函數最後一個參數為回調函數,回調函數的第一個參數包含了錯誤資訊(error)。

建議大家使用異步方法,比起同步,異步方法性能更高,速度更快,而且沒有阻塞。

檔案的寫入

同步

writeFileSync()

将要寫入的檔案内容完整的讀入緩存區,然後一次性的将緩存區中的内容寫入都檔案中(一次全部傳完)

writeFileSync(file, data[, options])

使用同步的方式讀取資料,且讀取的内容通過傳回值擷取。

  • file 要操作的檔案的路徑
  • data 要寫入的資料
  • options 選項,預設為null 也可直接傳入

    encoding

    • encoding 編碼,預設為

      utf8

    • flag 辨別位,預設為

      w

    • mode 權限位,預設為

      0o666

//引入fs子產品
var fs = require("fs");
fs.writeFile(
  "hello3.txt",
  "這是通過writeFile寫入的内容",
  { flag: "a" },
  function (err) {
    if (!err) {
      console.log("檔案寫入成功");
    }
  }
);
           

writeSync()

将需要寫入的資料寫入到一個記憶體緩存區,待緩存區寫滿後再将緩存區中的内容寫入到檔案中

1.打開檔案

fs.openSync(path, flags[, mode])

  • path 要打開檔案的路徑
  • flags 打開檔案要做的操作的類型
    • r 隻讀的
    • w 可寫的
  • mode 設定檔案的操作權限,一般不傳
  • 傳回值:該方法會傳回一個檔案的描述符作為結果,我們可以通過該描述符來對檔案進行各種操作

2.向檔案中寫入内容

fs.writeSync(fd, string[, position[, encoding]])

  • fd 檔案的描述符,需要傳遞要寫入的檔案的描述符
  • string 要寫入的内容
  • position 寫入的起始位置
  • encoding 寫入的編碼,預設utf-8

3.儲存并關閉檔案

fs.closeSync(fd)

  • fd 要關閉的檔案的描述符

eg:

var fs = require("fs");

//打開檔案
var fd = fs.openSync("hello.txt", "r");

//向檔案中寫入内容
fs.writeSync(fd, "今天天氣真不錯~~~");

//關閉檔案
fs.closeSync(fd);

console.log("程式向下執行~~~");

           

異步

writeFile()

writeFile(file, data[, options], callback)

将要寫入的檔案内容完整的讀入緩存區,然後一次性的将緩存區中的内容寫入都檔案中(一次全部傳完,檔案過大就會影響效率)

  • file 要操作的檔案的路徑
  • data 要寫入的資料
  • options 選項,可以對寫入進行一些設定
  • callback 當寫入完成以後執行的函數
    • flag
      • r 隻讀
      • w 可寫
      • a 追加
const fs = require("fs");
 
fs.writeFile("2.txt", "Hello world", err => {
    if (!err) {
        fs.readFile("2.txt", "utf8", (err, data) => {
            console.log(data); // Hello world
        });
    }
});

           

write()

将需要寫入的資料寫入到一個記憶體緩存區,待緩存區寫滿後再将緩存區中的内容寫入到檔案中(分批次,存滿一個傳一個)

1.打開檔案

fs.open(path, flags[, mode], callback)

  • path:要打開檔案的路徑
  • flags:打開檔案要做的操作的類型
    • r 隻讀的
    • w 可寫的
  • mode:設定檔案的操作權限,一般不傳
  • callback:err錯誤對象,如果沒有錯誤則為null

2.向檔案中寫入内容

fs.write(fd, string[, position[, encoding]], callback)

  • fd 檔案的描述符,需要傳遞要寫入的檔案的描述符
  • string 要寫入的内容
  • position 寫入的起始位置
  • encoding 寫入的編碼,預設utf-8
  • callback:err錯誤對象,如果沒有錯誤則為null

3.儲存并關閉檔案

fs.close(fd, callback)

  • fd 要關閉的檔案的描述符

eg:

//引入fs子產品
var fs = require("fs");
//打開檔案
fs.open("hello2.txt", "w", function (err, fd) {
  //判斷是否出錯
  if (!err) {
    //如果沒有出錯,則對檔案進行寫入操作
    fs.write(fd, "異步檔案的寫入", function (err) {
      if (!err) {
        console.log("寫入檔案成功");
      }
      //關閉檔案
      fs.close(fd, function (err) {
        if (!err) {
          console.log("檔案關閉成功");
        }
      });
    });
  } else {
    console.log(err);
  }
});

console.log("程式向下執行")
//異步執行不會阻塞,是以最下面的 ”程式向下執行“ 最先輸出

/*輸出為:
  程式向下執行
  寫入檔案成功
  檔案關閉成功
*/
           

讀取檔案

同步

readFileSync()

readFileSync(path[, options])

  • path 要讀取的檔案的路徑
  • options 讀取的選項,預設值為

    null

    ,其中有

    encoding

    (編碼,預設為

    null

    )和

    flag

    (辨別位,預設為

    r

    ),也可直接傳入

    encoding

若現在有一個檔案名為

1.txt

,内容為 “Hello”,現在使用

readFileSync

讀取。

const fs = require("fs");
 
let buf = fs.readFileSync("1.txt");
let data = fs.readFileSync("1.txt", "utf8");
 
console.log(buf); // <Buffer 48 65 6c 6c 6f>
console.log(data); // Hello
           

readSync()

readSync(fd, buffer, offset, length, position)

方法将傳回一個 bytesRead (讀取的位元組數)

  • fd:檔案描述符,需要先使用 open 打開;
  • buffer:存儲将要寫入檔案資料的 Buffer;
  • offset:整數,從 Buffer 讀取資料的初始位置;
  • length:整數,讀取 Buffer 資料的位元組數;
  • position:整數,寫入檔案初始位置;

下面讀取一個

6.txt

檔案,内容為 “你好”。

var fs = require("fs");
let buf = Buffer.alloc(6);
fs.open("6.txt", "r", function (err, fd) {
  if (err) {
    console.error(err);
    return;
  }
  var bytesRead = fs.readSync(fd, buf, 0, 6, 0);
  console.log(bytesRead);
  console.log(buf);
  console.log(buf.toString());
});

// 6
// <Buffer e4 bd a0 e5 a5 bd>
// 你好
           

異步

readFile()

readFile(path[, options], callback)

  • 前兩個參數同上相同
  • callback回調函數,通過回調函數将讀取到内容傳回(err , data)
    • err 錯誤對象
    • data 讀取到的資料,會傳回一個Buffer

依然讀取

1.txt

檔案:

const fs = require("fs");
 
fs.readFile("1.txt", "utf8", (err, data) => {
    console.log(err); // null
    console.log(data); // Hello
});
           

read()

read

方法與

readFile

不同,一般針對于檔案太大,無法一次性讀取全部内容到緩存中或檔案大小未知的情況,都是多次讀取到 Buffer 中。

read(buffer, offset, length, position)

  • fd:檔案描述符,需要先使用 open 打開;
  • buffer:存儲将要寫入檔案資料的 Buffer;
  • offset:整數,從 Buffer 讀取資料的初始位置;
  • length:整數,讀取 Buffer 資料的位元組數;
  • position:整數,寫入檔案初始位置;
  • callback:回調函數,寫入完成後執行。
    • err(錯誤)
    • bytesWritten(實際寫入的位元組數)
    • buffer(被讀取的緩存區對象)

下面讀取一個

6.txt

檔案,内容為 “你好”。

const fs = require("fs");
let buf = Buffer.alloc(6);
 
// 打開檔案
fs.open("6.txt", "r", (err, fd) => {
    // 讀取檔案
    fs.read(fd, buf, 0, 3, 0, (err, bytesRead, buffer) => {
        console.log(bytesRead);
        console.log(buffer);
 
        // 繼續讀取
        fs.read(fd, buf, 3, 3, 3, (err, bytesRead, buffer) => {
            console.log(bytesRead);
            console.log(buffer);
            console.log(buffer.toString());
        });
    });
});
 
// 3
// <Buffer e4 bd a0 00 00 00>
 
// 3
// <Buffer e4 bd a0 e5 a5 bd>
// 你好
           

流式檔案的寫入 —— 推薦

同步、異步、簡單檔案的寫入都不适合大檔案的寫入,性能較差,容易導緻記憶體溢出

fs.createWriteStream(path[, options])

  • path,檔案路徑
  • options 配置的參數

可以通過監聽流的open和close事件來監聽流的打開和關閉

var fs = require("fs");

//流式檔案寫入
//建立一個可寫流
var ws = fs.createWriteStream("hello3.txt");

//可以通過監聽流的open和close事件來監聽流的打開和關閉
/*
  on(事件字元串,回調函數)
    - 可以為對象綁定一個事件

  once(事件字元串,回調函數)
    - 可以為對象綁定一個一次性的事件,該事件将會在觸發一次以後自動失效

**/
ws.once("open",function () {
  console.log("流打開了~~~");
});

ws.once("close",function () {
  console.log("流關閉了~~~");
});

//通過ws向檔案中輸出内容
ws.write("通過可寫流寫入檔案的内容");
ws.write("今天天氣真不錯");
ws.write("鋤禾日當午");
ws.write("紅掌撥清清");
ws.write("清清真漂亮");

//關閉流
ws.end();
           

流式檔案的讀取

fs.createReadStream(path[, options])

流式檔案讀取也适用于一些比較大的檔案,可以分多次将檔案讀取到記憶體中

  • path,檔案路徑
  • options 配置的參數
var fs = require("fs");
//建立一個可讀流
var rs = fs.createReadStream("hello3.txt");

//建立一個可寫流
var ws = fs.createWriteStream("hello5.txt");

//監聽流的開啟和關閉
rs.once("open", function () {
  console.log("可讀流打開了~~");
});
rs.once("close", function () {
  console.log("可讀流關閉了~~");
});

ws.once("open", function () {
  console.log("可寫流打開了~~");
});
ws.once("close", function () {
  console.log("可寫流關閉了~~");
  ws.end();
});

// pipe()可以将可讀流中的内容,直接輸出到可寫流中
rs.pipe(ws);

           

繼續閱讀