Node.js Buffer、fs同步和異步(寫入,讀取)簡單(寫入、讀取)流式(寫入、讀取)

Buffer緩衝區

JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型,所以Buffer就是用來存儲二進制文件的。

但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。一個 Buffer 類似於一個整數數組,但它對應於 V8 堆內存之外的一塊原始內存。

在v6.0之前創建Buffer對象直接使用new Buffer()構造函數來創建對象實例,但是Buffer對內存的權限操作相比很大,可以直接捕獲一些敏感信息,所以在v6.0以後,官方文檔裏面建議使用 Buffer.from() 接口去創建Buffer對象

Buffer 與字符編碼

Buffer 實例一般用於表示編碼字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六進制編碼的數據。 通過使用顯式的字符編碼,就可以在 Buffer 實例與普通的 JavaScript 字符串之間進行相互轉換。

在緩衝區和字符串之間進行轉換時,可以指定字符編碼。如果沒有指定字符編碼,將使用UTF-8作爲默認值。

const buf = Buffer.from('runoob', 'ascii');

// 輸出 72756e6f6f62
console.log(buf.toString('hex'));

// 輸出 cnVub29i
console.log(buf.toString('base64'));

 

Node.js 目前支持的字符編碼包括:

  • ascii - 僅支持 7 位 ASCII 數據。如果設置去掉高位的話,這種編碼是非常快的。

  • utf8 - 多字節編碼的 Unicode 字符。許多網頁和其他文檔格式都使用 UTF-8 。

  • utf16le - 2 或 4 個字節,小字節序編碼的 Unicode 字符。支持代理對(U+10000 至 U+10FFFF)。

  • ucs2 - utf16le 的別名。

  • base64 - Base64 編碼。

  • latin1 - 一種把 Buffer 編碼成一字節編碼的字符串的方式。

  • binary - latin1 的別名。

  • hex - 將每個字節編碼爲兩個十六進制字符。

Buffer 使用

直接使用不需要引入模塊,直接使用即可。

Buffer 類是一個全局變量,用於直接處理二進制數據。 它可以使用多種方式構建。

Buffer.from(array)#

新增於: v5.10.0

使用 0 – 255 範圍內的字節數組 array 來分配一個新的 Buffer。 超出該範圍的數組條目會被截斷以適合它。

// 創建一個包含字符串 'buffer' 的 UTF-8 字節的新 Buffer。
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);

如果 array 不是一個 Array 或適用於 Buffer.from() 變量的其他類型,則拋出 TypeError

Buffer.from(array) 和 Buffer.from(string) 也可以像 Buffer.allocUnsafe() 一樣使用內部的 Buffer 池。

Buffer.alloc(size[, fill[, encoding]])

  • size <integer> 新 Buffer 的所需長度。
  • fill <string> | <Buffer> | <Uint8Array> | <integer> 用於預填充新 Buffer 的值。默認值: 0
  • encoding <string> 如果 fill 是一個字符串,則這是它的字符編碼。默認值: 'utf8'
const b = Buffer.alloc(10,"李連杰","utf8");
console.log(b.toString());

Buffer.allocUnsafe(size)

  • size <integer> 新建的 Buffer 的長度。

創建一個大小爲 size 字節的新 Buffer。 如果 size 大於 buffer.constants.MAX_LENGTH 或小於 0,則拋出 ERR_INVALID_OPT_VALUE

以這種方式創建的 Buffer 實例的底層內存是未初始化的。 新創建的 Buffer 的內容是未知的,可能包含敏感數據。 使用 Buffer.alloc() 可以創建以零初始化的 Buffer 實例。

const buf = Buffer.allocUnsafe(10);
console.log(buf);
// 打印(內容可能有所不同): <Buffer a0 8b 28 3f 01 00 00 00 50 32>
buf.fill(0);
console.log(buf);
// 打印: <Buffer 00 00 00 00 00 00 00 00 00 00>

對比Buffer.alloc(size[, fill[, encoding]])和Buffer.allocUnsafe(size)

alloc:安全,效率低

allocUnsafe:不安全,效率高,會泄露敏感信息。

fs的同步和異步調用:

  • fs模塊中所有的操作都有兩種形式可以選擇,同步異步
  • 同步晚間系統會阻塞程序的運行,也就是除非操作完畢,否則不會向下執行代碼。
  • 異步文件系統不會阻塞程序的執行,二是在操作完成時,通過回調函數將結果返回。

fs寫入文件 

同步文件寫入

1.打開文件

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

   'r'就是隻讀

   'w'就是可寫

        設置文件的操作權限,一般用於Linux。

  • 返回: <number>返回表示文件描述符的整數。

     返回一個描述符,相當於標誌,實際值沒有意義,就相當於給你打開的文件起個別名,以後你就可以將其作爲這個文件的標誌。

2.寫入文件

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

  fd <integer> 文件描述符,需要傳遞要寫入文件的文件描述符

3.關閉文件

fs.closeSync(fd)

fd <integer>

同步的 close(2)。返回 undefined

通過任何其他 fs 操作在當前正在使用的任何文件描述符(fd)上調用 fs.closeSync() 可能導致未定義的行爲。

fs同步寫入文件

//引入fs模塊
const  fs = require("fs");
//打開一個文件
var file = fs.openSync("./hello.txt",'w');
console.log("文件描述符:"+file);
fs.writeSync(file,"今天很高興學習fs文件寫入!");
fs.closeSync(file);

fs異步寫入文件

1.打開文件

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

中英對照提交修改

path <string> | <Buffer> | <URL>

mode 用於設置文件模式(權限和粘滯位),但僅限於創建文件時。 在 Windows 上,只能操作寫權限,參見 fs.chmod()

回調有兩個參數 (err, fd)

有些字符 (< > : " / \ | ? *) 在 Windows 上是預留的,參見命名文件、路徑以及命名空間。 在 NTFS 上,如果文件名包含冒號,則 Node.js 會打開文件系統流,參見此 MSDN 頁面

基於 fs.open() 的函數也會表現出以上行爲,比如 fs.writeFile()、 fs.readFile() 等。

//引入fs模塊
const  fs = require("fs");
//打開一個文件
fs.open("./hello2.txt","w",function (error,fd) {
    console.log("文件描述符:"+fd);
    if(error){
       console.log(error);
    }else{
       fs.writeSync(fd,"今天很高興學習fs文件寫入!");
    }
       fs.closeSync(fd);

})

簡單文件寫入

異步

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

當 file 是文件名時,則異步地寫入數據到文件(如果文件已存在,則覆蓋文件)。 data 可以是字符串或 buffer。

當 file 是文件描述符時,則其行爲類似於直接調用 fs.write()(建議使用)。 參見以下關於使用文件描述符的說明。

如果 data 是 buffer,則 encoding 選項會被忽略。

const data = new Uint8Array(Buffer.from('Node.js 中文網'));
fs.writeFile('文件.txt', data, (err) => {
  if (err) throw err;
  console.log('文件已被保存');
});
//引入fs模塊
const  fs = require("fs");
//寫入一個文件
fs.writeFile("hello3.txt","這是通過writeFile寫入的內容",function (error) {
    if(!error){
        console.log("寫入成功:");
     }
})

同步

fs.writeFileSync(file, data[, options])

返回 undefined

//引入fs模塊
const  fs = require("fs");
//打開文件
fs.open('hello4.txt', 'a', function(err,fd){
    if(err){
        throw err;
    }
    var data = '同步簡單寫入';
    var buf = new Buffer(8);
    fs.writeSync(fd, buf, 0, 8, 0);
    fs.close(fd,function(err){
        if(err){
            throw err;
        }
        console.log('file closed');
    })
})

流式文件寫入

1創建一個可寫流

fs.createWriteStream(path[, options])

2通過可寫流寫入內容
//流式文件寫入
const fs  =  require("fs");
//創建可寫流
const  fw = fs.createWriteStream("hello.txt");
//通過可寫流寫入內容
fw.write("通過可寫流寫入文件的內容0");
fw.write("通過可寫流寫入文件的內容1");
fw.write("通過可寫流寫入文件的內容2");
fw.once("open",function () {
    console.log("流打開了~~~");
})
//關閉輸出方的流
fw.end();

注意:流式寫入關閉的時候要關閉輸入方的流,不能關閉接受方的流,因爲寫入方只需將內容傳送到流(水管)中就可以關閉了,但是如果接受方關閉流的話,就相當於主動拔掉水管不接受水管中的內容。

fs讀取文件

同步

fs.readFileSync(path[, options])

返回 path 的內容。

異步:

fs.readFile(path[, options], callback)#

異步地讀取文件的全部內容。

同步和異步如下:

var  fs = require('fs');
//導入文件模塊
//node 同步讀文件
var  sycContext  = fs.readFileSync("hello.txt",{flag:'r',encoding:"UTF-8"});
console.log(content.toString());
//node 異步讀文件,
var  content = fs.readFile("hello.txt",{flag:'r',encoding:"UTF-8"},function (err,data) {
    if(err){
        console.log(err);
    }else{
        console.log(data);
    }
});

簡單文件讀取

const fs  =  require("fs");
const path = "zz.jpg";
const content = fs.readFile(path,{flag:'r'},function (err,data) {
    if(err){
        console.log(err);
    }else{
        fs.writeFile("dog.jpg",data,function () {
            console.log(data);
        })
    }
});

 

流式文件讀取

如果要讀取一個可讀流中的數據,必須腰圍可讀流綁定一個事件,data事件綁定完畢,它會自動開始讀取數據。

const fs  =  require("fs");
const fr = fs.createReadStream("hello.txt");
fr.once("open",function () {
    console.log("流打開了");
})

fr.on("data",function (data) {
    console.log(data,data.length);
})

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

文件操作狀態

模式

說明

r

讀取文件,文件不存在則出現異常

r+

讀寫文件,文件不存在則出現異常

rs

在同步模式下打開文件用於讀取

rs+

在同步模式下打開文件用於讀取

w

打開文件用於寫操作,如果不存在則創建,如果存在則截斷(幹掉)

wx

打開文件用於寫操作,如果存在則打開失敗

w+

打開文件用於讀寫,如果不存在則創建,如果存在則截斷(幹掉)

wx+

打開文件用於讀寫,如果存在則打開失敗

a

打開文件用於追加,如果不存在則創建

ax

打開文件用於追加,如果文件路徑存在則失敗

a+

打開文件進行讀取和追加,如果不存在則創建該文件

ax+

打開文件進行讀取和追加,如果路徑存在則失敗

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章