node之fs模塊

__filename: 獲取當前模塊的帶有完整絕對路徑的文件名
__dirname: 獲取當前模塊文件是所在目錄的完整絕對路徑

1.buffer(Buffer類)

Buffer為將應用程序中的二進制數據的存儲與轉換提供一個緩存區

toString(): 將緩存區中內容轉換為字符串

const data = new Buffer('我喜愛編程');
data.toString();

new Buffer();
isBuffer();
Buffer.concat([str1, str2], 6);

2.event()

3.file(fs模塊)

同步VS異步

readFile, readFileSync ,帶有sync的是同步方法,否則為異步方法,兩者區別: 同步方法立即返回操作結果,在使用同步方法執行的操作結束之前,不能執行后續代碼

var fs = require('fs');
var data = fs.readFileSync('./index.html', 'utf8');
// console.log(data);
fs.readFile('./index.html', 'utf8', (err, data) => {
    // 操作結果作為回調函數的第二個參數返回
    console.log(data);
})

大多數情況使用異步;特殊場景(例如讀取文件配置并啟動服務器,),應該使用同步方法

對文件完成讀寫

讀文件

異步

fs.readFile(filename, [options], callback);

filename: 必填,指定讀取文件的完整文件路徑及文件名
options: 可選,是一個對象,

  • flag屬性指定對改文件采取什么操作,
    默認值為'r'(如果指定讀取的文件不存在,則拋出異常);
    'r+': 讀取并寫入文件,如果文件不存在則拋出異常
    'rs': 以同步方式讀取文件并通知操作系統忽略文件系統緩存,文件不存在則創建文件
    'w': 寫入文件,文件不存在則創建改文件,問津已存在則清空文件內容
    'wx': 作用與'w'類似,但是以排他方式寫入文件
    'w+': 讀取并寫入該文件,如果文件不存在則創建文件,如果存在則清空文件內容
    'a': 追加寫入文件,文件不存在則創建文件
    'a+':讀取并追加寫入文件,如果不存在則創建該文件
    'ax': 作用與'a+'類似,但是以排他方式寫入文件
  • encoding屬性指定編碼格式('utf8', 'ascii', 'base64'),默認為一個存放了文件原始二進制內容的緩存區對象;
    callback: 讀取完畢執行的回調操作
function(err, data) {

}

同步

const data = fs.readFileSync(filename, [options]);
var fs = require('fs');
try {
    var data = fs.readFileSync('./index1.html', 'utf8');
    console.log(data);
} catch(err) {
    console.log('讀取文件時發生錯誤');
}

寫入文件

fs.writeFile(filename, data, [options], callback);

filename: 指定需要被寫入文件的完整文件路徑及文件名;
data: 字符串或一個Buffer對象,該字符串或緩存區的內容將被完整地寫入到文件中
option:

  • flag: 默認為'w'(文件不存在時創建該文件, 文件已存在時,重寫該文件)
  • mode: 指定當文件被打開時該文件的讀寫權限,默認值為066(可讀寫);
  • encoding: 指定使用何種編碼格式來寫入文件, data參數為一個Buffer對象時改屬性克忽略,使用默認編碼格式utf8來執行文件的寫入
    callback: 回調函數使用一個參數,參數數值為寫入文件操作失敗時觸發的錯誤對象
function(err) {

}

復制'a.jpg'到'b.jpg'

fs.readFile('./a.jpg', 'base64', (err, data) => {
    // 操作結果作為回調函數的第二個參數返回
    fs.writeFile('./b.jpg', data.toString(), 'base64',  (err) => {
        if(err) {
            console.log('寫文件失敗');
        } else {
            console.log('寫文件成功');
        }
    })
})

同步

fs.writeFileSync(filename, data, [options]);

將一個字符串或者一個緩存區中的數據追加到一個文件底部,使用fs模塊中的appendFile方法或者appendFileSync

fs.appendFile(filename, data, [option], callback);
fs.appendFileSync(filename, data, [option])

參數含義同writeFile,區別是options的flag屬性的默認值為'a'(在文件底部追加數據,如果文件不存在,則創建 該文件);

從指定位置開始讀寫

fs.open(filename, flags, [model], callback);

callback參數用于指定 文件打開操作 執行完畢時執行的回調函數

function(err, fd) {
    // 回調函數代碼簡略
}

第二個參數是一個整數值,代表打開文件時返回的文件描述符(在windows操作系統中,文件描述符亦稱文件句柄);

var fd = fs.openSync(filename, flags, [model]);

打開文件之后,可以用read或readSync方法從文件指定位置處讀取文件,可以使用write或writeSync方法從文件的指定處開始寫入數據

read:從文件的指定位置處讀取文件,一直讀取到的內容輸出到一個緩存區

fs.read(fd, buffer, offset, length, position, callback);

fd:open方法的回調函數中返回的文件描述符或openSync方法返回的文件描述符
buffer: 一個Buffer對象,用于指定將文件數據讀取到哪個緩存區
offset:用于指定向緩存區中寫入數據的開始寫入位置(以字節為單位)
length:指定從文件讀取的字節數
position:指定讀取文件時的開始位置(以字節為單位)
callback:

function (err,bytesRead, buffer) {

}
  • err: 讀取文件操作失敗時所觸發的錯誤對象,
  • bytesRead: 一個整數值,代表實際讀取的字節數(由于文件的開始讀取位置+指定讀取的字節數可能大于文件長度,指定讀取的字節數可能并不等于實際讀取的字節數)
  • buffer:被讀取到的緩存區對象

從應用程序的根目錄下的內容為'我喜愛編程'字符串的test.txt文件將'喜愛編'這三個字符讀取到一個緩存區,然后從緩存區中讀取出這三個字符

var fs = require('fs');
fs.open('./test.txt', 'r', (err, fd) => {
   var buf = new Buffer(225);
   fs.read(fd, buf, 0, 9, 3, (err, bytesRead, buffer) => {
       console.log(buffer.slice(0, bytesRead).toString());
   })
})

同步

var bytesRead = fs.readSync(fd, buffer, offset, length, position);

可以使用fs的write或writeSync方法從一個緩存區中讀取數據并且從一個文件的指定處開始寫入這些數據

fs.write(fd, buffer, offset, length. position, callback);

function(err, written, buffer) {
    // written為一個整數值,代表被寫入的字節數
}

使用'我喜愛編程'字符串創建一個緩存區然后使用write方法從緩存區讀取'喜愛編'這三個字符并將其寫入到應用程序根目錄message.txt文件中

var buf = new Buffer('我喜愛編程');
fs.open('./message.txt', 'w', (err, fd) => {
    fs.write(fd, buf, 3, 9, 0, (err, written, buffer) => {
        if(err) {
            console.log('寫入文件失敗');
        }
        console.log('寫入文件成功', written, buffer)
    })
})

寫入文件成功 9 <Buffer e6 88 91 e5 96 9c e7 88 b1 e7 bc 96 e7 a8 8b>

當對文件的讀寫操作執行完畢后,我們通常需要關閉該文件,尤其是在文件以排他方式被打開的時候;
fs模塊中提供了close及closeSync方法以關閉文件

fs.close(fd, [callback]);
fs.closeSync(fd);

使用write或writeSync方法在文件中時,操作系統 的做法是首先將該部分數據讀到內存中,再把數據寫到文件中,當數據讀完時不代表數據已經寫完,因為還有一部分有可能留在內存緩存區,這時使用close方法關閉文件,那么這部分數據就會丟失,這時可以使用fs模塊中的fsync方法對文件進行同步操作,即將內存緩沖區中的剩余數據全部寫入文件

fs.fsync(fd, [callback]);
fs.fsyncSync(fd);

創建目錄

fs.mkdir(path, [mode], callback);
fs.mkdirSync(path, [mode]);

path:指定需要被創建的目錄完整路徑及目錄名
mode: 指定該目錄的權限,默認值為0777(表示任何人可讀寫該目錄)
callpack: 創建目錄操作完畢時調用的回調函數,參數值為創建目錄失敗時觸發的錯誤對象;

讀取目錄

fs.readdir(path, [callback]);
const files = fs.readdirSync(path);

path: 需要被讀取的目錄的完整路徑及目錄名
callback

function(err, files) {

}

files: 是一個數組,其中存放了讀取到的文件中所有的文件名

查看問阿金或目錄的信息

stat方法或者lstat方法查看一個文件或目錄的信息,當查看符號鏈接文件的信息時,必須使用lstat方法

fs.stat(path, callback);
fs.lstat(path, callback);

path: 需要被查看的文件或目錄的完整路徑及文件名或目錄名
callpack:

function(err, stats) {

}

stats: 是一個fs.stats對象
使用open或openSync打開文件后可以使用fstat查看文件的方法

fs.fstat(fd, [callback]);
const stats = fs.fstatSync(fd);

檢查目錄是否存在

fs.exists(path, callback);
const exists = fs.existsSync(path);

callpack: 一個參數,文件或目錄存在時,該參數值為true,當文件和目錄不存在時,該參數值為false

function(exists) {

}

獲取文件或目錄的絕對路徑

fs.realpath(path, [cache], callback)

callpack:

function(err, resolvedPath) {

}

resolvedPath: 獲取到的文件或目錄的絕對路徑

修改文案訪問時間及修改時間

fs.utimes(path, atime, mtime, callpack);
fs.utimesSync(path, atime, mtime);

atime: 指定修改后的訪問時間
mtime:指定修改后的修改時間;
callpack: 一個參數,修改文件時間操作失敗時觸發的錯誤對象

使用open或openSync打開文件并返回文件描述符后可以使用futimes修改文件的訪問時間或修改時間

fs.futimes(fs, atime, mtime,callback);
fs.futimesSync(fs, atime, mtime);

修改文件或目錄的讀寫權限

fs.chmod(path, mode, callback);
fs.chmodSync(path, mode);
fs.fchmod(fd, mode, callback);
fs.fchmodSync(fd, mode);

移動文件或目錄

fs.rename(oldPath, newPath, callback);
fs.renameSync(oldPath, newPath);

創建與刪除文件的硬鏈接

硬鏈接: 文件的一個或者多個文件名,在操作系統,一個文件被創建之后就擁有了一個文件名,因此該文件的硬鏈接數據為1,但是我們可以通過特殊操作為改文件再指定一個文件名,這種特殊操作稱為對改文件創建鏈接;表面上看起來擁有兩個不同的文件,但是在硬盤中這兩個文件不過是同一個文件的多個硬鏈接,如果修改一個文件的內容再打開另一個文件,發現,文件被修改

fs.link(srcpath, dstpath,callback);
fs.linkSync(srcpath, dstpath);

srcpath: 指定需要被創建硬鏈接的文件的完整路徑及文件名
dstpath: 指定被創建硬鏈接的文件的完整路徑及文件名

刪除文件的硬鏈接

fs.unlink(path, callpack);
fs.unlinkSync(path)

path: 指定被刪除硬鏈接操作完畢時調用的函數

創建與查看符號鏈接

符號鏈接: 一種特殊的文件,這個文件包含了另一個文件或目錄的路徑及文件名或目錄名,如果打開一個文件的符號鏈接文件進行編輯,操作系統將自動打開符號鏈接中所指向的原文件進行編輯

創建文件或目錄的鏈接符號

fs.symlink(srcpath, dstpath, [type], callback);
fs.symlinkSync(srcpath, dstpath, [type]);

srcpath: 需要被創建符號鏈接的文件或目錄的完整路徑及文件或目錄名
dstpath: 指定被創建符號鏈接的文件或目錄的完整路徑及文件或目錄名
type: 可選,指定為文件創建符號鏈接還是為目錄創建符號鏈接

  • file: 為文件創建符號鏈接
  • dir:目錄(非windows操作系統中只能使用dir參數值)

讀取符號鏈接中所包含的另一個文件或目錄的路徑及目錄名

fs.readlink(path, callback);

funciton(err, linkString) {
    // linString: 讀取到的一個鏈接字符串,另一個文件或目錄的路徑及目錄名
}


var linkString = fs.readlinkSync(path);
  • path: 指定符號鏈接的路徑及文件名

截斷文件

fs.truncate(filename, len, callback);
fs.truncateSync(filename, len);

fs.ftruncate(fd ,len, callback);
fs.ftruncate(fd, len, callback);

  • len: 整數數值, 用于指定被截斷后的文件尺寸(以字節為單位);

刪除空目錄

fs.rmdir(path, callback);
fs.rmdirSync(path);

監視文件或目錄

fs.watchFile(filename, [options], listener);

options: 一個對象

  • persistent: 布爾值, 指定了被監視的文件后是否停止當前正在運行的應用程序,默認值為true
  • interval: 每隔多少毫秒監視一次文件是否發生改變以及發生了什么改變

listener: 指定當被監視的文件發生改變時調用的回調函數

funciton(curr, prev) {

}

curr參數值為一個fs.Stats對象,代表被修改之后的當前文件;
prev參數值為一個fs.Stats對象,代表被修改之前的當前文件;

文件流

readFile/readFileSync: 將文件完整讀入緩存區
read/readSync: 將文件部分讀入緩存區
writeFile/writeFileSync: 將數據完整寫入文件
write/writeSync: 將文件中的部分內容寫入文件

readFile/readFileSync 讀取文件內容 或者 writeFile/writeFileSync 寫入文件內容時,Node.js將文件內容視為一個整體,為其分配緩存區并且一次性將文件內容讀取到緩存區,在這個期間,Node.js將不能執行任何其他處理
如果使用read/readSync 方法讀取文件內容,Node.js將不斷地將文件中一小塊內容讀取入暫存區,如果使用write/writeSync, 執行過程如下:
1.將需要書寫的數據寫入到一個內存緩存區
2.待緩存區寫滿后再講改緩存區中內容寫入到文件中
3.重復執行1和2,知道數據全部寫入文件為至
也就是在讀寫的過程中允許Node.js執行其他處理

Node.js中可以使用flowing模式與非flowing模式來讀取數據,使用flowing模式時,操作系統的內部I/O機制來讀取數據,以最快的速度來讀取數據,使用非flowing模式,必須顯式調用對象的read方法來讀取數據

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容