nodejs操作文件和數據流

来源:https://www.cnblogs.com/flypig-322/archive/2019/01/15/10269589.html
-Advertisement-
Play Games

前言 node中有一組流api,它們可以像處理網路流一樣處理文件。流api用起來非常方便,本節學習介紹文件處理基礎和流的概念。 目錄 1. 處理文件路徑 處理文件路徑需要用到一個核心模塊(path),path模塊可以規範化、連接、解析路徑,還可以將絕對路徑轉換為相對路徑,提取路徑的組成以及判斷路徑是 ...


前言

  node中有一組流api,它們可以像處理網路流一樣處理文件。流api用起來非常方便,本節學習介紹文件處理基礎和流的概念。

目錄

  1. 處理文件路徑
  2. fs核心模塊簡介
  3. 操作流
  4. 慢客戶端問題

1. 處理文件路徑

  處理文件路徑需要用到一個核心模塊(path),path模塊可以規範化、連接、解析路徑,還可以將絕對路徑轉換為相對路徑,提取路徑的組成以及判斷路徑是否存在。

1.1. 規範化路徑

在存儲和使用路徑前最好能夠將其進行規範化,這裡使用path模塊的normalize()函數

1 //規範化路徑
2 var path=require('path');
3 path.normalize('/pathstudy//path1')
4 // =>'/pathstudy/path1'

 

1.2. 連接路徑

通過path.join()函數可以連接多個路徑字元串,如下所示:

1 //連接路徑
2 var path=require('path');
3 path.join('/pathstudy','path1','test');
4 // => '/pathstudy/path1/test'

 

1.3. 解析路徑

使用path.resolve()函數將多個路徑解析為一個規範化的路徑

1 //解析路徑
2 var path=require('path');
3 path.resolve('/foo/bar','./dd');
4 // =>/foo/bar/dd
1.4. 提取路徑的組成部分
1 //提取路徑組成部分
2 var path=require('path');
3 path.dirname('/foo/bar/dd/a1.txt');//獲取文件路徑的目錄 => /foo/bar/dd
4 path.basename('/foo/bar/dd/a1.txt');//獲取文件名 => a1.txt
5 path.basename('/foo/bar/dd/a1.txt','.txt');//獲取不包含文件類型的文件名 => a1
6 path.extname('/foo/bar/dd/a1.txt','.txt');//獲取文件擴展類型 =>.txt
1.5. 判斷路徑是否存在

使用path.exists()函數判斷路徑是否存在,0.8版本以後使用fs.exists()函數代替,只需將導入模塊替換為fs即可。

1 //判斷路徑是否存在
2 var path=require('path');
3 path.exists('/foo/bar/dd',function(exists){
4     console.log('是否存在:',exists);
5 })

2. fs模塊簡介

fs核心模塊內置查詢文件信息和打開/讀寫/關閉文件操作

查詢文件信息

使用fs.stat()函數查詢文件特征,例如大小、創建時間、許可權等

//查詢文件信息
var fs=require('fs');
fs.stat('/foo/bar/dd',function(stats){
    console.log(stats);//列印出文件信息
    stats.isFile();//判斷是否文件
    stats.isDirectory();//判斷是否目錄
    stats.isSocket();//判斷是否UNIX套接字
    //...
});
打開/讀寫/關閉文件
 1 var fs=require('fs');
 2 //打開文件,‘r’表示模式類型
 3 fs.open('/foo/bar/dd/a1.txt','r',function(err,fd){
 4     //獲取文件描述符 fd
 5 });
 6 
 7 //讀取文件
 8 fs.open('/foo/bar/dd/a1.txt','r',function(err,fd){
 9     if(err){
10         throw err;
11     }
12     var readbuffer=new Buffer(1024),//設置緩衝區
13         bufferOffset=0,
14         filePosition=100,//從100位元組開始
15         bufferLength=readbuffer.length;//讀取隨後的1024位元組數據;
16         fs.read(fd,readbuffer,bufferOffset,bufferLength,filePosition,
17             function (err, readBytes){
18                 if(err){
19                     throw err;
20                 }
21                 if(readBytes>0){
22                     console.log(readbuffer.slice(0,readBytes));//獲取讀入緩衝區的位元組數
23                 }
24             });
25 });
26 
27 //寫入文件
28 fs.open('/foo/bar/dd/a1.txt','a',function(err,fd){
29     if(err){
30         throw err;
31     }
32     var writebuffer=new Buffer('準備寫入緩衝區的數據'),//設置緩衝區
33         bufferPosition=0,//寫入起始位置
34         filePosition=null,//從文件什麼位置開始寫 
35         bufferLength=readbuffer.length;//長度
36         fs.write(fd,writebuffer,bufferPosition,bufferLength,filePosition,
37             function (err, write){
38                 if(err){
39                     throw err;
40                 }
41                 console.log('write bytes:',write);//獲取讀入緩衝區的位元組數
42             });
43 });
44 
45 //關閉文件
46 fs.open('/foo/bar/dd/a1.txt','a',function(err,fd){
47     if(err){
48         throw err;
49     }
50     //write...
51     //close
52     fs.close(fd,function(){
53         //...
54     })
55 });
View Code

文件模式類型:

r——數據流的位置從起始處打開文件讀取

r+——數據流的位置從起始處打開文件讀寫

w——如果文件存在則清零,不存在則創建文件並寫入數據,數據流的位置從文件起始處

w+——打開文件進行讀寫,如果文件存在則清零,不存在則創建文件並寫入數據,數據流的位置從文件起始處

a——打開文件寫入數據,如果文件存在則清零,不存在則創建文件,數據流的位置從文件結尾處,寫操作都將追加到文件後面

a+——打開文件讀寫數據,如果文件存在則清零,不存在則創建文件,數據流的位置從文件結尾處,寫操作都將追加到文件後面

需要註意,在讀寫文件操作回調函數執行之後,不要使用提供的緩衝區,不然可能會導致讀寫數據不完整。

3. 操作流

流是由幾個node對象實現的抽象概念,創建或讀取流的方式取決於使用流的類型,流的特性包含可讀流可寫流,通過監聽data事件,在流每次提交數據時,都能夠得到通知。

3.1. 創建文件系統流
 1 var fs=require('fs');
 2 //根據文件路徑創建一個可讀流
 3 fs.createReadStream('/foo/bar/file');
 4 
 5 fs.open('/foo/bar/file','r',function(err,fd){
 6     fs.createReadStream(null,{fd:fd,encoding:'utf8'});
 7     fs.on('data',function(data){
 8         console.log('data:',data);
 9     });
10 });
11 
12 //創建可寫流
13 fs.createWriteStream('/foo/bar/file');
14 
15 fs.createWriteStream('/foo/bar/file',option);
16 //option表示第二個參數,預設值為{flags:'w',encoding:null,mode:0666}

 

可以指定createReadStream和createWriteStream函數的第二個參數,用來設置文件的起始結束位置、編碼格式等等,參數選項如下所示:

  • encoding——data事件發送的編碼格式
  • fd——如果已經有一個打開文件描述符則可以傳入該參數選項
  • bufferSize——要被讀取的每個文件塊大小,單位是位元組,預設64kb
  • start——設置文件中第一個被讀取的位元組位置,用來限制讀取數據範圍
  • end——與start相反
  • flags——表示用於打開文件的模式類型
  • mode——指定要打開文件的許可權

4. 慢客戶端問題

當客戶端的網路連接速度較慢時,可寫流也就慢速,可讀流會快速產生data事件並監聽,數據被髮送到可寫流,導致node不得不緩存數據導致緩衝區被快速填滿。

一般情況可以通過暫停數據生產者來避免這個問題:

 1 var http=require('http');
 2 var fs=require('fs');
 3 http.createServer(function(req,res){
 4     var rs= fs.createReadStream('/foo/bar/file');
 5 
 6     rs.on('data',function(data){
 7         if(!res.write(data)){
 8             rs.pause();//暫停可讀流
 9         }
10     });
11 
12     rs.on('drain',function(){
13         rs.resume();//恢復可讀流
14     });
15 
16     rs.on('end',function(){
17         res.end();//結束操作
18     });
19 
20 }).listen('8080');
View Code

擴展:使用pipe函數操作上述暫停/恢復操作

 1 var http=require('http');
 2 var fs=require('fs');
 3 http.createServer(function(req,res){
 4     var rs= fs.createReadStream('/foo/bar/file');
 5     rs.pipe(res);//由傳輸源調用並接受目標可寫流作為參數
 6 }).listen('8080');
 7 
 8 http.createServer(function(req,res){
 9     var rs= fs.createReadStream('/foo/bar/file');
10     //預設情況下end()在可讀流結束時在可寫流上被調用,設置第二個參數end選項為false表示不讓pipe函數進行end操作
11     rs.pipe(res,{end:false});
12 
13     rs.on('end',function(){
14         res.write('endend~~');
15         res.end();//結束操作
16     });
17 }).listen('8080');
View Code

總結

對於流我表示比較懵逼,對概念理解的還不是很透徹。。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 移動研發火熱不停,越來越多人開始學習android開發。但很多人感覺入門容易成長很難,對未來比較迷茫,不知道自己技能該怎麼提升,到達下一階段需要補充哪些內容。市面上也多是談論知識圖譜,缺少體系和成長節奏感,特此編寫一份android研發進階之路,希望能對大家有所幫助。 這篇文章里,我們只談技術 ...
  • 說明:閱讀本文章,請參考之前的block文章加以理解; 一、棧區block分析 //代碼 //列印 分析: <1>block代碼內部引用的Person實例對象先於輸出語句銷毀,因為per僅限於大括弧內,但此時block銷毀了沒有?往下看; <2>上述block代碼塊並沒有被指針持有,接下來看看指針持 ...
  • Swift中Array的刪除對象 在Swift中數組Array沒有removeObject的方法 1、找到下標 let model_index = selectedArray.index(where: { (arr) -> Bool in ((selectedBeaconArray.index(of ...
  • 1.JavaScript 迴圈 如果希望一遍又一遍地運行相同的代碼,並且每次的值都不同,那麼使用迴圈是很方便的。 我們可以這樣輸出數組的值: 一般寫法: for迴圈寫法: 結果: 2.不同類型的迴圈 JavaScript 支持不同類型的迴圈: for - 迴圈代碼塊一定的次數 for/in - 迴圈 ...
  • 一,效果圖。 二,代碼。 參考資料:《菜鳥教程》 ...
  • datagrid 設置內容超過單元格寬度時自動換行顯示 by:授客 QQ:1033553122 測試環境 jquery-easyui-1.5.3 問題描述 單元格內容超過單元格寬度不會自動化換行。如下: 圖1: 圖2: 解決方法 定義表格時,設置nowrap屬性為false. <table id=' ...
  • 分別用JavaScript,jQuery和vue做了一個簡單的購物車加減按鈕部分。 HTML: css(主要是去除按鈕預設樣式,賦予新樣式): JavaScript: jQuery: vue版 HTML: vue: ...
  • 一、flex flex是flexible box的縮寫,意為“彈性佈局”; 定義彈性佈局 display:flex; 二、基本定義 我只簡單的說一下容器和項目,因為只關係容器和項目來講的(個人理解)。 三、 容器的屬性 有6個屬性 一下對6個容器屬性的簡單介紹 1. flex-direction屬性 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...