1. 程式人生 > 其它 >Node.js基礎入門第四天

Node.js基礎入門第四天

經過前面三天的學習,Node.js的基礎知識已逐漸掌握,今天繼續學習快取區和檔案操作,並稍加整理加以分享,如有不足之處,還請指正。

快取區

1. 什麼是快取區?

JavaScript語言自身只有基本資料型別(如:字串),沒有二進位制資料型別。二進位制資料可以儲存電腦中任何資料(如:一段文字,一張圖片等)。Node.js作為服務端,在處理TCP網路流或檔案流時,必須使用到二進位制資料。因此在Node.js中定義了一個Buffer類,用來建立一個專門存放二進位制資料的快取區。所以快取區就是在記憶體中開闢一個臨時用於儲存需要運算的位元組碼的區域。

2. 建立指定長度的快取區

在Node.js中提供了一個Buffer物件,可以直接建立指定長度的快取區,如下所示:

1 var buffer = Buffer.alloc(10);;
2 buffer.write('abcdefghij');
3 console.log(buf);

示例輸出結果,如下所示:

通過以上示例可以看出,寫入的一串英文字元,在快取區中是以十六進位制格式顯示的。

關於字元的十六進行表示,可以參考ASCII ((American Standard Code for Information Interchange): 美國資訊交換標準程式碼)

ASCII ((American Standard Code for Information Interchange): 美國資訊交換標準程式碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是最通用的資訊交換標準,並等同於國際標準ISO/IEC 646。ASCII第一次以規範標準的型別發表是在1967年,最後一次更新則是在1986年,到目前為止共定義了128個字元 [1]  。示例

如下所示:

 

 在快取區儲存漢字的時候,也會轉換成UTF-8編碼的位元組碼,並以十六進位制表示,如下所示:

1 var buffer = Buffer.alloc(10);
2 buffer.write('張三');
3 console.log(buffer);

示例如下所示:

 

通過以上示例,可以看出,在Node.js中,採用UTF-8編碼,1個英文字元佔1個位元組;1箇中文漢字3-4個位元組(UTF-8編碼是變長的)。

3. 通過陣列建立快取區

在Node.js中,通過陣列建立快取區,如下所示:

1 var buffer = Buffer.from([97,98,99,100,101,102]);
2 console.log(buffer); 3 console.log(buffer.toString());

示例結果如下:

通過以上示例看出,陣列的格式是十進位制整數,儲存到快取區時,轉換成了十六進行表示。

4. 通過字串建立快取區

Buffer.from方法,不僅可以通過陣列建立,還可以傳入字串內容,如下所示:

1 var buffer = Buffer.from("我是小六子呀!");
2 console.log(buffer);
3 console.log(buffer.toString());

示例結果如下所示:

5. 讀寫快取區

在Node.js中,通過toString方法讀取快取區的內容,通過write方法寫入快取區。如下所示:

1 var buffer = Buffer.alloc(10);
2 buffer.write('張三');
3 console.log(buffer.toString());

示例如下:

6. 複製快取區

通過copy方法,可以將快取區內容從一個快取區拷貝到新的快取區。如下所示:

1 var buffer = Buffer.from("我是小六子呀!");
2 var buffer2 = Buffer.alloc(21);
3 console.log("複製前",buffer2);
4 buffer.copy(buffer2);
5 console.log("複製後:",buffer2);

示例結果如下所示:

 

檔案操作

Node.js作為服務端程式,新增了讀取檔案操作。檔案I/O操作是對標準POSIX函式的簡單封裝,通過require('fs')使用該模組,所有方法都有同步和非同步的方式。讀寫檔案主要有兩種方式:a.直接讀取,b.流式讀取

1. 非同步直接讀取

將硬碟上的所有內容全部讀入記憶體以後才觸發回撥函式。如下所示:

1 var fs =require('fs');
2 fs.readFile('./test.txt',function(err,data){
3     if(err){
4         console.log(err);
5     }else{
6         console.log(data.toString());//預設data為Buffer型別
7     }
8 });

示例如下所示:

 

2. 同步直接讀取

同步方式直接返回資料內容,不再使用回撥函式,如下所示:

1 var fs =require('fs');
2 var data = fs.readFileSync('./test.txt');
3 console.log(data.toString());

3. 流式讀取

當需要讀取的檔案比較大時,無法一次讀取完成,則需要採用流式讀取的方式,將資料從硬碟中一節一節的讀取。迴圈讀取一節就觸發回撥函式,以實現大檔案操作。

假如現在有一個檔案,採用流式讀取,如下所示:

1 var fs =require('fs');
2 //建立流
3 var stream=fs.createReadStream('./test.txt');
4 //監控流獲取資料事件
5 stream.on('data',function(data){
6     console.log('--------------------------');
7     console.log(data.length);
8     console.log(data);
9 });

讀取示例如下所示:

 

通過以上示例可以看出,每一次位元組流讀取的資料大小為65536位元組,即64KB。如果檔案大小大於64KB,則會分為多節進行讀取。

4. 寫入檔案

寫入檔案與讀取檔案相對,如下所示:

1 var fs =require('fs');
2 var test="這周都沒有上班了,在居家辦公,好不方便呀!!!";
3 fs.writeFile('./test1.txt',test,function(err){
4     if(err){
5         console.log(err);
6     }else{
7         console.log('儲存成功');
8     }
9 });

示例如下:

 檔案預設為utf-8編碼,如下所示:

同步寫入就是在非同步寫入的方法後加入Sync即可。

5. 流式寫入檔案

位元組流的方式寫入檔案,如下所示:

1 var fs =require('fs');
2 var stream = fs.createWriteStream('./input.txt');
3 stream.write("小六子瀟灑呀");
4 stream.write("小六公子瀟灑呀");
5 stream.write("小六痞子瀟灑呀");
6 stream.end();

寫入成功後,檔案如下:

注意,流式寫入檔案,一定要有end方法結束位元組流。位元組流還有其他事件,如:end,finish,error,都可以通過on進行監聽。

6. 讀取檔案資訊

Node.js不僅可以讀取寫入檔案內容,還可以讀取檔案資訊,如檔案大小,建立時間等內容,如下所示:

1 var fs =require('fs');
2 fs.stat('./test.txt',function(err,stat){
3     if(err){
4         console.log(err);
5     }else{
6         console.log(stat);
7     }
8 });

讀取檔案資訊返回的是一個物件,包含檔案的各個屬性,示例結果如下所示:

 

 注意:返回的Stat物件,同時包含isFile和isDirectory方法,用於判斷路徑是否檔案和資料夾。

7. 刪除檔案

刪除檔案可以採用unlink方法,如下所示:

1 var fs =require('fs');
2 fs.unlink('./test.txt',function(err){
3     if(err){
4         console.log(err);
5     }else{
6         console.log('刪除成功');
7     }
8 });

如果要刪除的檔案不存在,則會返回錯誤資訊,如果存在,則提示刪除成功。示例結果如下所示:

8. 管道

管道(pipe)提供了一個輸出流到輸入流的機制。

通常我們複製大檔案,採用從一個流中獲取資料,並將資料傳遞到另外一個流中。如下所示:

 1 var fs =require('fs');
 2 var s1=fs.createReadStream('./test.txt');
 3 var s2 = fs.createWriteStream('./input.txt');
 4 //以流的方式實現大檔案複製,讀取一節,傳遞一節
 5 s1.on('data',function(data){
 6     s2.write(data);
 7 });
 8 s1.on('end',function(){
 9     s2.end();
10     console.log('檔案複製完成');
11 });

以上方式稍微有點複雜,採用管道方式,可以簡化操作,如下所示:

1 var fs =require('fs');
2 var s1=fs.createReadStream('./test.txt');
3 var s2 = fs.createWriteStream('./input.txt');
4 s1.pipe(s2);//管道方式

9. 鏈式流

將資料流通過管道連結起來,實現鏈式管理。如壓縮等方式。

1 var fs =require('fs');
2 var zlib =require('zlib');
3 var s1=fs.createReadStream('./test.txt');
4 var s2 = fs.createWriteStream('./test.zip');
5 s1.pipe(zlib.createGzip()).pipe(s2);

備註

蝶戀花·春景【作者】蘇軾 【朝代】宋

花褪殘紅青杏小。燕子飛時,綠水人家繞。枝上柳綿吹又少。天涯何處無芳草。

牆裡鞦韆牆外道。牆外行人,牆裡佳人笑。笑漸不聞聲漸悄。多情卻被無情惱。