每天學點node系列-fs文件系統

来源:https://www.cnblogs.com/jingh/archive/2019/07/09/11161170.html
-Advertisement-
Play Games

好的代碼像粥一樣,都是用時間熬出來的。 概述 文件 I/O 是由簡單封裝的標準 POSIX 函數提供的。 通過 require('fs') 使用該模塊。 所有文件系統操作都具有同步和非同步的形式。 非同步的形式總是將完成回調作為其最後一個參數。 傳給完成回調的參數取決於具體方法,但第一個參數始終預留用於 ...


好的代碼像粥一樣,都是用時間熬出來的。

概述

文件 I/O 是由簡單封裝的標準 POSIX 函數提供的。 通過 require('fs') 使用該模塊。

所有文件系統操作都具有同步和非同步的形式。

非同步的形式總是將完成回調作為其最後一個參數。 傳給完成回調的參數取決於具體方法,但第一個參數始終預留用於異常。 如果操作成功完成,則第一個參數將為 null 或 undefined

// 非同步示例
const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('已成功刪除 /tmp/hello');
});

使用同步的操作發生的異常會立即拋出,可以使用 try/catch 處理,也可以允許冒泡。

//同步示例
const fs = require('fs');

try {
  fs.unlinkSync('/tmp/hello');
  console.log('已成功刪除 /tmp/hello');
} catch (err) {
  // 處理錯誤
}

在進程中,建議使用非同步版本。 同步的版本將阻塞整個進程,直到它們完成(停止所有連接)。但是非同步操作不保證執行順序所以,所以在使用時請註意使用對象執行順序。

文件系統標誌

flags可以是:

'a' - 打開文件用於追加。如果文件不存在,則創建該文件。
'ax' - 與 'a' 相似,但如果路徑已存在則失敗。
'a+' - 打開文件用於讀取和追加。如果文件不存在,則創建該文件。
'ax+' - 與 'a+' 相似,但如果路徑已存在則失敗。
'as' - 以同步模式打開文件用於追加。如果文件不存在,則創建該文件。
'as+' - 以同步模式打開文件用於讀取和追加。如果文件不存在,則創建該文件。
'r' - 打開文件用於讀取。如果文件不存在,則出現異常。
'r+' - 打開文件用於讀取和寫入。如果文件不存在,則出現異常。
'rs+' - 以同步模式打開文件用於讀取和寫入。指示操作系統繞過本地的文件系統緩存。
'w' - 打開文件用於寫入。如果文件不存在則創建文件,如果文件已存在則截斷文件。
'wx' - 與 'w' 相似,但如果路徑已存在則失敗。
'w+' - 打開文件用於讀取和寫入。如果文件不存在則創建文件,如果文件已存在則截斷文件。
'wx+' - 與 'w+' 相似,但如果路徑已存在則失敗。

底層介面

打開文件

非同步打開

// fs.open
path <string> | <Buffer> | <URL>
flags <string> | <number> 參閱支持的文件系統標誌。
mode <integer> 預設值: 0o666(可讀寫)。
callback <Function>
  - err <Error>
  - fd <integer>
var fs = require('fs')
fs.open('1.txt','r',function(err,fs){
    console.log(err)
    console.log(fs)
})

執行結果:

$ node 1.js
null
3

註意: 使用'rs+'模式不會使fs.open()進入同步阻塞調用。如果那是你想要的,則應該使用fs.openSync()

同步打開

// fs.openSync
path <string> | <Buffer> | <URL>
flags <string> | <number> 參閱支持的文件系統標誌。
mode <integer> 預設值: 0o666。
返回: <number>
返回表示文件描述符的整數。
var fs = require('fs');
var result = fs.openSync('1.txt','r');
console.log(result);

執行結果:

$ node 1.js
3

讀取文件

fd <integer> 從 fd 指定的文件中讀取數據。
buffer <Buffer> | <TypedArray> | <DataView> 數據將寫入的緩衝區。
offset <integer> buffer 中開始寫入的偏移量
length <integer> 是一個整數,指定要讀取的位元組數
position <integer> 參數指定從文件中開始讀取的位置。 如果 position 為 null,則從當前文件位置讀取數據,並更新文件位置。 如果 position 是整數,則文件位置將保持不變。
callback <Function>
- err <Error>
- bytesRead <integer>
- buffer <Buffer>
var fs = require('fs');
fs.open('1.txt','r',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        var bf = Buffer.alloc(5);
        fs.read(fd,bf,0,3,null,function(err,len,buffer){
            console.log(err);
            console.log(len);
            console.log(buffer);
        })
    }
});

執行結果:

$ node 1.js
null
3
<Buffer 68 65 6c 00 00>

同步讀取

fd <integer>
buffer <Buffer> | <TypedArray> | <DataView>
offset <integer>
length <integer>
position <integer>
返回: <number>
返回 bytesRead 的數量。
var fs = require('fs');
var fd = fs.openSync('1.txt','r');
var bf = Buffer.alloc(5);
var result = fs.readSync(fd,bf,0,3,null);
console.log(result);

執行結果:

$ node 1.js
3

寫入文件

fd <Integer>  文件標識
buffer <String> | <Buffer> 要將buffer中的數據寫入到文件中
offset <Integer> buffer對象中要寫入的數據的起始位置
length <Integer> length是一個整數,指定要寫入的位元組數
position <Integer> 指定從文件開始寫入數據的位置的偏移量。 如果 typeof position !== 'number',則數據從當前位置寫入
callback <Function> 回調有三個參數(err, written, buffer),其中written指定從buffer寫入了多少位元組

執行結果

$ node 1.js
null
3
<Buffer 74 65 73 74>

[註意]多次對同一文件使用fs.write且不等待回調,是不安全的。對於這種情況,強烈推薦使用 fs.createWriteStream  當我們要對打開的文件進行寫操作的時候,打開文件的模式應該是讀寫模式

同步寫入

fd <integer>
buffer <Buffer> | <TypedArray> | <DataView>
offset <integer>
length <integer>
position <integer>
返回: <number> 寫入的位元組數。
var fs = require('fs');
var fd = fs.openSync('1.txt','r+');
var bf = Buffer.alloc(5);
var result = fs.writeSync(fd,bf,0,3,null);
console.log(result);

執行結果:

$ node 1.js
3

關閉文件

fd - 通過 fs.open() 方法返回的文件描述符。
callback - 回調函數,沒有參數。
var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        fs.close(fd, function(err){
            if (err){
                console.log(err);
            } 
            console.log("文件關閉成功");
        });
    }
});
$ node 1.js
文件關閉成功

同步關閉

var fs = require('fs');
var fd = fs.openSync('1.txt','r+');
fs.closeSync(fd);

文件操作

文件讀取

同步讀取

// fs.readFileSync
path <string> | <Buffer> | <URL>
options <string> | <Object>
    encoding <string> 預設值: 'utf8'。
    withFileTypes <boolean> 預設值: false。

返回: <string[]> | <Buffer[]> | <fs.Dirent[]>
var fs = require('fs');
var data;

try{
    data = fs.readFileSync('./1.txt', 'utf8');
    console.log('文件內容: ' + data);
}catch(err){
    console.error('讀取文件出錯: ' + err.message);
}

執行結果為:

$ node 1.js
文件內容: hello rock

非同步讀取

// fs.readFile
path <string> | <Buffer> | <URL>
options <string> | <Object>
    - encoding <string> 預設值: 'utf8'。
    - withFileTypes <boolean> 預設值: false。
callback <Function>
    - err <Error>
    - files <string[]> | <Buffer[]> | <fs.Dirent[]>
var fs = require('fs');

fs.readFile('./1.txt', 'utf8', function(err, data){
    if(err){
        return console.error('讀取文件出錯: ' + err.message);
    }
    console.log('文件內容: ' + data);
});

執行結果也為:

$ node 1.js
文件內容: hello rock

通過文件流讀取

適合讀取大文件

path <string> | <Buffer> | <URL>
options <string> | <Object>
   - flags <string> 參閱支持的文件系統標誌。預設值: 'r'。
   - encoding <string> 預設值: null。
   - fd <integer> 預設值: null。
   - mode <integer> 預設值: 0o666。
   - autoClose <boolean> 預設值: true。
   - start <integer>
   - end <integer> 預設值: Infinity。
   - highWaterMark <integer> 預設值: 64 * 1024。
返回: <fs.ReadStream> 參閱[可讀流]。
var fs = require('fs');
var readStream = fs.createReadStream('./1.txt', 'utf8');

readStream
    .on('data', function(chunk) {
        console.log('讀取數據: ' + chunk);
    })
    .on('error', function(err){
        console.log('出錯: ' + err.message);
    })
    .on('end', function(){  // 沒有數據了
        console.log('沒有數據了');
    })
    .on('close', function(){  // 已經關閉,不會再有事件拋出
        console.log('已經關閉');
    });

執行結果:

$ node 1.js
讀取數據: hello rock
沒有數據了
已經關閉

文件寫入

非同步寫入

// fs.writeFile
file <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。
data <string> | <Buffer> | <TypedArray> | <DataView>
options <Object> | <string>
  - encoding <string> | <null> 預設值: 'utf8'。
  - mode <integer> 預設值: 0o666。
  - flag <string> 參閱支持的文件系統標誌。預設值: 'w'。
callback <Function>
  - err <Error></Error>
var fs = require('fs');
fs.writeFile('./1.txt', 'hello rock', 'utf8', function(err){
    if(err) throw err;
    console.log('文件寫入成功');
});

執行結果:

$ node 1.js
文件寫入成功

同步寫入

// fs.writeFileSync
file <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。
data <string> | <Buffer> | <TypedArray> | <DataView>
options <Object> | <string>
  - encoding <string> | <null> 預設值: 'utf8'。
  - mode <integer> 預設值: 0o666。
  - flag <string> 參閱支持的文件系統標誌。預設值: 'w'。
  
返回 undefined。
var fs = require('fs');
try{
    fs.writeFileSync('./1.txt', 'hello rock', 'utf8');
    console.log('文件寫入成功');
}catch(err){
    throw err;
}

執行結果:

$ node 1.js
文件寫入成功

通過文件流寫入

path <string> | <Buffer> | <URL>
options <string> | <Object>
   - flags <string> 參閱支持的文件系統標誌。預設值: 'w'。
   - encoding <string> 預設值: 'utf8'。
   - fd <integer> 預設值: null。
   - mode <integer> 預設值: 0o666。
   - autoClose <boolean> 預設值: true。
   - start <integer>
返回: <fs.WriteStream> 參閱可寫流。
var fs = require('fs');
var writeStream = fs.createWriteStream('./1.txt', 'utf8');
writeStream
    .on('close', function(){ // 已經關閉,不會再有事件拋出
        console.log('已經關閉');
    });
writeStream.write('hello');
writeStream.write('rock');
writeStream.end('');

執行結果:

$ node 1.js
已經關閉

追加文件

file - 文件名或文件描述符。
data - 要寫入文件的數據,可以是 String(字元串) 或 Buffer(流) 對象。
options - 該參數是一個對象,包含 {encoding, mode, flag}。預設編碼為 utf8, 模式為 0666 , flag 為 'w'
callback - 回調函數,回調函數只包含錯誤信息參數(err),在寫入失敗時返回。
var fs = require('fs');
var filename = '1.txt';
fs.appendFile(filename,' world',function(err){
    console.log(err);
})

執行結果

$ node 1.js
null

同步追加

var fs = require('fs');
var filename = '1.txt';
fs.appendFileSync(filename,' lalala');

刪除文件

path - 文件路徑。
callback - 回調函數,沒有參數。
var fs = require('fs');
var filename = '1.txt';
fs.unlink(filename, function(err) {
   if (err) {
       return console.log('刪除失敗');
   }
   console.log("刪除成功");
});

執行結果:

$ node 1.js
刪除成功

同步刪除

var fs = require('fs');
var filename = '1.txt';
fs.unlink(filename);

重命名

oldPath <String> | <Buffer>
newPath <String> | <Buffer>
callback <Function> 回調只有一個可能的異常參數
var fs = require('fs');
var filename = 'a.txt';
fs.rename(filename,'2.new.txt',function(err){
    console.log(err);
})
$ node 1.js
null

同步重命名

var fs = require('fs');
var filename = '2.new.txt';
var result = fs.renameSync(filename,'a.txt');

文件信息

path <string> | <Buffer> | <URL>
options <Object>
bigint <boolean> 返回的 fs.Stats 對象中的數值是否應為 bigint 型。預設值: false。
callback <Function>
   - err <Error>
   - stats <fs.Stats>
var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
    console.log(err);
    console.log(stats);
});

執行結果

$ node 1.js
null
Stats {
  dev: 163689085,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: undefined,
  ino: 9007199254854088,
  size: 0,
  blocks: undefined,
  atimeMs: 1562684836201.136,
  mtimeMs: 1562684836201.136,
  ctimeMs: 1562684998231.913,
  birthtimeMs: 1562684836201.136,
  atime: 2019-07-09T15:07:16.201Z,
  mtime: 2019-07-09T15:07:16.201Z,
  ctime: 2019-07-09T15:09:58.232Z,
  birthtime: 2019-07-09T15:07:16.201Z }

stats類中的方法有

stats.isFile()  如果是文件返回 true,否則返回 false。
stats.isDirectory() 如果是目錄返回 true,否則返回 false。
stats.isBlockDevice()   如果是塊設備返回 true,否則返回 false。
stats.isCharacterDevice()   如果是字元設備返回 true,否則返回 false。
stats.isSymbolicLink()  如果是軟鏈接返回 true,否則返回 false。
stats.isFIFO()  如果是FIFO,返回true,否則返回false。FIFO是UNIX中的一種特殊類型的命令管道。
stats.isSocket()    如果是 Socket 返回 true,否則返回 false。
var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
    console.log(stats.isFile());//true
});

監聽

filename <String> | <Buffer>
options <String> | <Object> 參數可選,如果options是一個字元串,則它指定了encoding。否則options應該以一個對象傳入
    persistent <Boolean> 指明如果文件正在被監視,進程是否應該繼續運行。預設為true
    recursive <Boolean> 指明是否全部子目錄應該被監視,或只是當前目錄。 適用於當一個目錄被指定時,且只在支持的平臺。預設為false
    encoding <String> 指定用於傳給監聽器的文件名的字元編碼。預設為'utf8'
listener <Function> 回調函數有兩個參數 (eventType, filename)。 eventType可以是'rename'或'change',filename是觸發事件的文件的名稱
fs.watch('txt', (eventType, filename) => {
  console.log(`事件類型是: ${eventType}`);
  if (filename) {
    console.log(`提供的文件名: ${filename}`);
  } else {
    console.log('未提供文件名');
  }
});
var fs = require('fs');
var filename = '1.txt';
fs.watch(filename,function(eventType, _filename){
    console.log(eventType);//change
    if(_filename){
        console.log(_filename + '發生了改變');//'1.txt發生了改變'
    }else{
        console.log('...');
    }
    
})

[註意]當一個文件出現或消失在一個目錄里時,'rename'也會被觸發


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

-Advertisement-
Play Games
更多相關文章
  • 第一步:手機連接到itunes 選擇本電腦備份 備份的時候不要加密 然後立即備份 第二步:前往文件夾,找到itunes的備份路徑~/Library/Application Support/MobileSync/Backup 在這目錄下搜索 3d0d開頭的文件,這就是 iPhone 簡訊的資料庫文件。 ...
  • 目前iOS組件化常用的解決方案是Pod+路由+持續集成,通常架構設計完成後第一步就是將原來工程里的模塊按照架構圖分解為一個個獨立的pod工程(組件),今天我們就來看看如何創建一個Pod私有庫。 新建:pod lib create 假設我們需要創建的庫名為TestLib,下麵我們使用Pod官方提供的創 ...
  • jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“Write Less, Do More”,即倡導寫更少的代碼,做更多的事情。它封裝JavaScript常用的功能代碼,提供... ...
  • 解釋CSS3 中新增的選擇器中最具有代表性的就是序選擇器,大致可以分為兩類: (1)同級別的第幾個(2)同類型的第幾個 先寫一個公共代碼 1.選中同級別中的第一個 註意點:不區分類型,只管取第一個,不管第一個是什麼標簽 解釋:在同級別中只選取第一個為h1標簽和div下的p標簽,然後在這些裡面只選p標 ...
  • Javascript是前端面試的重點,本文重點梳理下 Javascript 中的常考基礎知識點,然後就一些容易出現的題目進行解析。限於文章的篇幅,無法將知識點講解的面面俱到,本文只羅列了一些重難點。 ...
  • Vue.js提供了v-model指令用於雙向數據綁定,比如在輸入框上使用時,輸入的內容會事實映射到綁定的數據上,綁定的數據又可以顯示在頁面里,數據顯示的過程是自動完成的。 v-model本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。例如: 渲染如下: 當我 ...
  • 背景 在Electron打開新視窗的時候,提前載入一段JavaScript腳本,以此內置一些屬性或介面給被打開的頁面。之所以要以註入方式,而不是頁面自己引用,原因是不想麻煩頁面自行引用,不想修改舊有的業務邏輯。 方法一 一開始是想在打開BrowserWindow後,執行executeJavaScri ...
  • 先鋪墊下原型規則: 1.所有的引用類型(數組,對象,函數)都具有對象特性,可自由擴展屬性(出了null外) 2.所有的引用類型(數組,對象,函數)都有一個__proto__屬性(隱式原型),屬性值是一個對象 3.所有的函數都有一個prototype屬性(顯示原型),屬性值是一個對象 4.所有的引用類 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...