閱讀目錄
一:如何讀整個文件內容?
注意:讀取文件和寫入文件可能理解很枯燥,但是我每次學習這樣的文章的時候都是為了下一篇文章做好准備的,因為我下一篇文章的demo需要使用到該方面的知識,所以我就會把需要的理解的知識統統記錄一遍的。
在Node.js中,使用fs模塊來實現所有文件及目錄的創建,寫入及刪除操作。
1. 讀文件的方法:
在執行讀文件操作時,可以使用readFile方法與readFileSync方法讀取文件,有Sync等字樣的是同步方法,沒有這個字樣的是異步方法讀取,同步方法和異步方法的區別是:同步方法立即返回操作的結果,先看下相關的API:
1)readFileSync同步讀取文件API
使用方法讀取如下:
fs.readFileSync(filename, [options]);
filename參數:用於指定讀取文件的完整文件路徑及文件名。
options參數:該值為一個對象,它可以指定讀取文件時使用flag屬性指定該文件采取什么操作,默認為 'r'; 可以指定值有如下:
'r': 讀取文件,如果文件不存在會拋出異常。
'r+': 讀取並寫入文件,如果文件不存在會拋出異常。
'rs': 同步方式讀取文件並且通知操作系統忽略本地文件系統的緩存,如果文件不存在會拋出異常。
'w': 寫入文件,如果文件不存在則創建該文件,如果文件已存在則清空文件內容。
'w+': 讀取並寫入文件,其他功能和 'w'一樣。
'a': 追加寫入文件,如果文件不存在則創建該文件。
'a+': 讀取並追加寫入文件,文件不存在就創建文件。
在options參數中,我們可以使用 encoding屬性指定使用何種編碼格式來讀取該文件,屬性值有 'utf-8', 'ascii', 'base64', 下面先看看簡單的demo。如下所示:
先看下目錄結構如下:
### 目錄結構如下: demo1 # 工程名 | |--- readFile # 讀取文件的文件夾 | | |-- index.html # html文件 | | |-- index.js # js文件 | | |-- package.json | | |-- node_modules
如下代碼讀取文件代碼:
const fs = require('fs');
try {
const data = fs.readFileSync('./index.html', 'utf-8');
// 等待操作結果返回,然后打印結果
console.log(data);
} catch(e) {
console.log('讀取文件發生錯誤');
}
在命令行中執行 node index.js 然后打印結果如下:

2) 異步讀取文件的API使用方法如下:
fs.readFile(filename, [options], callback);
filename 和 options 和 同步方法的參數是一樣的。
callback參數 是用於文件讀取完后執行的回調函數。如下代碼所示:
const fs = require('fs');
fs.readFile('./index.html', 'utf-8', (err, data) => {
if (err) {
console.log('讀取文件時發生錯誤');
} else {
console.log(data);
}
});
執行的結果和上面是一樣的。這里就不截圖了。
二:如何寫入整個文件內容?
寫入文件,我們使用fs模塊中的 writeFile 方法 或 wirteFileSync方法。writeFile使用方法如下(wirteFileSync方法類似,無非沒有callback參數):
fs.writeFile(filename, data, [options], callback);
filename參數 為指定需要被寫入文件的完整路徑及文件名。
data參數 為指定需要寫入的內容,值可以是一個字符串或一個Buffer對象,該字符串或緩沖區中的內容將被完整地寫入到文件中。
options值為一個對象(可選),選項名為flag,它有如下選項值:
'flag': 用於指定該文件采取何種操作,默認值為 'w', 含義是寫入文件。該指定項所有值和上面readFile的值是一樣的。
(文件不存在就創建該文件,文件存在時重寫該文件)。
'mode': 該屬性用於指定當文件被打開時對該文件的讀寫權限。默認值為 0666(可讀寫)。還有很多值自己可以百度了解下。
'encoding': 用於指定使用何種編碼格式來寫入該文件。可指定屬性值為 'utf8'、'ascii'、'base64'。
callback: 該參數用於文件讀取完畢時執行的回調函數。
下面我們簡單的做一個demo,在我們目錄下的 index.js 文件中編寫代碼,在該目錄下創建一個 message.txt文件並寫入兩行文字。如下代碼:
const fs = require('fs');
const str = '這是第一行。\r\n這是第二行';
fs.writeFile('./message.txt', str, (err) => {
if (err) {
console.log('寫入文件操作失敗');
} else {
console.log('寫入文件操作成功');
}
});
如下圖執行命令:

在目錄下會生成 message.txt文件,如下圖

然后我們打開文件,會看到其寫入的內容。
2)寫入buffer對象,如下代碼:
const fs = require('fs');
const str = new Buffer('我喜愛編程');
fs.writeFile('./message.txt', str, (err) => {
if (err) {
console.log('寫入文件操作失敗');
} else {
console.log('寫入文件操作成功');
}
});
在message.txt中可以看到 '我喜愛編程' 幾個字。
3)設置options參數flag屬性選項,比如追加數據這些,如下代碼:
const fs = require('fs');
const options = {
flag: 'a'
};
fs.writeFile('./message.txt', '這是追加的數據', options, (err) => {
if (err) {
console.log('寫入文件操作失敗');
} else {
console.log('寫入文件操作成功');
}
});
message.txt內容編程如下了:我喜愛編程這是追加的數據
4)復制圖片文件
我們可以通過readFile方法讀取應用程序對應目錄下的一個圖片文件,在讀取文件時使用base64編碼,在該回調函數中使用writeFile方法,在該方法中使用base64編碼將讀取到的圖片文件數據復制到另一個圖片文件中。如下代碼:
const fs = require('fs');
fs.readFile('./images/1.png', 'base64', (err, data) => {
fs.writeFile('./images/xx.png', data.toString(), 'base64', (err) => {
if (err) {
console.log('寫文件操作失敗');
} else {
console.log('寫文件操作成功');
}
});
});
在image下有一個 1.png, 它會先復制,然后寫入 xx.png中(該文件之前不存在的,會創建該圖片文件)。
三:如何在文件中的指定位置處讀入內容?
3.1)打開文件open方法或openSync方法
要實現在文件中的指定位置處讀入內容,首先我們需要打開該文件,fs模塊中的open方法或openSync方法打開文件。open方法使用方式如下所示:
fs.open(filename, flags, [mode], callback);
前三個參數和readFile的參數是一個意思的。最后一個參數是執行完成后的回調函數。該回調函數有兩個參數,第一個是打開文件失敗時的錯誤對象,第二個參數為一個整數值,代表打開文件時返回的文件描述符。
下面我們來打開我們剛剛創建的 message.txt文件,如下代碼:
const fs = require('fs');
fs.open('./message.txt', 'r', (err, fd) => { console.log(fd); });
執行結果如下所示:

3.2)從指定的位置讀取文件
如上面打開文件之后,我們可以在其回調函數使用fs模塊中的read方法或readSync方法從文件的指定位置處讀取文件,也可以使用fs模塊中的write方法或writeSync方法從文件中指定處寫入數據。
fs.read(fd, buffer, offset, length, position, callback);
fd參數是 上面open打開文件返回的文件描述符。
buffer參數 是一個buffer對象,用於指定將文件數據讀取到那個緩存區中。
offset:用於指定向緩沖區中寫入數據的開始位置。
length:用於指定從文件中讀取的字節數。
position: 用於指定讀取文件時的開始位置。
callback:用於指定文件操作完畢時的回調函數。如下所示:
function(err, bytesRead, buffer) {}
err: 為操作失敗時的錯誤對象。
bytesRead: 代表實際讀取的字節數。
buffer:為被讀取的緩沖區對象。
下面我們來看個demo代碼如下:
const fs = require('fs');
// message.txt 內容為:我喜愛編程這是追加的數據
fs.open('./message.txt', 'r', (err, fd) => { const buf = new Buffer(255); // 一個漢字的utf編碼為三個字節數據 fs.read(fd, buf, 0, 9, 3, (err, bytesRead, buffer) => { console.log(buffer.slice(0, bytesRead).toString()); // 喜愛編 }); });
如上代碼message.txt內容為:我喜愛編程這是追加的數據,position為3,從第三個字節開始讀取文件,然后長度為9個字節,一個漢字3個字節,因此結果為 '喜愛編';
四:如何在文件中的指定位置處寫入內容?
在文件被打開后,可以使用fs模塊中的write方法或writeSync方法從一個緩存區中讀取數據並從文件的指定位置處寫入這些數據。使用方法如下所示:
fs.write(fd, buffer, offset, length, position, callback);
fd參數為描述符。
buffer參數為一個Buffer對象,用於指定從哪個緩存區中讀取數據。
offset參數用於指定從緩存區中讀取數據時的開始讀取位置。
length參數用於指定從緩存區中讀取的字節數。
position參數值用於指定寫入文件時的開始位置。
callback參數用於指定文件寫入操作執行完畢時的回調函數。該回調函數如下:
function(err, written, buffer) {}
err參數為寫入失敗時的錯誤對象。
written: 代表被寫入的字節數。
buffer: 代表被讀取的緩沖區對象。
下面是一個簡單的demo,如下所示:
const fs = require('fs');
const buf = new Buffer('我喜愛編程');
fs.open('./message.txt', 'w', (err, fd) => {
fs.write(fd, buf, 3, 9, 0, (err, written, buffer) => {
if (err) {
console.log('寫文件操作失敗');
} else {
console.log('寫文件操作成功');
}
});
});
在message.txt中顯示為 喜愛編 這三個字。
五:如何創建與讀取目錄?
5.1) 創建目錄mkdir和mkdirSync方法
在fs模塊中,可以使用mkdir方法創建目錄,該方法使用方式如下所示:
fs.mkdir(path, [mode], callback);
path參數用於指定需要被創建的目錄完整路徑及目錄名。
mode參數用於指定該目錄的權限,默認值為0777(表示任何人可讀寫該目錄)。
callback是回調函數。
下面是一個簡單的demo,如下所示:
const fs = require('fs');
fs.mkdir('./test', (err) => {
if (err) {
console.log('創建目錄操作失敗');
} else {
console.log('創建目錄操作成功');
}
});
如下所示:

5.2)讀取目錄readdir和readdirSync方法
在fs模塊中,使用readdir方法讀取目錄,該方法使用如下所示:
fs.readdir(path, callback);
path參數用於指定需要被讀取的目錄的完整路徑及目錄名。
callback參數用於指定讀取目錄操作的回調函數。該回調函數如下所示:
function(err, file) {}
err 為讀取目錄操作失敗的回調函數。
file參數值為一個數組,讀取到的文件中的所有文件名。
如下demo所示:
const fs = require('fs');
fs.readdir('./', (err, files) => {
if (err) {
console.log('讀取目錄操作失敗');
} else {
console.log(files);
}
});
如下圖所示:

六:如何查看與修改文件或目錄的信息?
6.1)查看文件或目錄的信息
在fs模塊中,可以使用stat方法或lstat方法查看一個文件或目錄的信息。這兩個方法唯一的區別是當查看符號鏈接文件的信息
時,必須使用lstat方法。使用方法如下所示:
fs.stat(path, callback);
fs.lstat(path, callback);
path參數用於被查看的文件或目錄的完整路徑及文件名或目錄名。
callback是回調函數。如下回調函數
function(err, stats) {}
err 參數值為查看文件或目錄信息操作失敗時觸發的錯誤對象。
stats參數值為一個 fs.Stats對象,該對象有如下一些方法,在這些方法中不包含任何參數。
isFile: 用於判斷被查看的對象是否為一個文件,如果是則返回true,否則的話返回false。
isDirectory: 用於判斷被查看的對象是否為一個目錄,如果是的話返回true,否則的話返回false。
還有很多很多其他的方法,這里不一一介紹,用的比較少,有需要的話,可以自己百度一下看看。
下面是使用 stat的使用demo,查看應用程序根目錄下的 message.txt文件並且在回調函數中的第二個參數值 fs.Stats對象在控制台中的輸出有哪些?
const fs = require('fs');
fs.stat('./message.txt', (err, stats) => {
console.log(stats);
});
如下圖所示顯示:

6.2)檢查文件或目錄是否存在exists和existsSync方法
在fs模塊中,可以使用exists方法檢查一個文件或目錄是否存在,該方法使用方式如下所示:
fs.exists(path, callback);
path參數:用於指定需要被檢查的文件或目錄的完整路徑。
callback: 是回調函數,該回調函數如下所示:
function(exists) {}
exists參數,當文件或目錄存在時,該參數值為true,否則的話,該參數值為false。
下面是一個簡單的demo,如下代碼所示:
const fs = require('fs');
// 該目錄是存在的
fs.exists('./message.txt', (exists) => {
console.log(exists); // true
});
// 該目錄是不存在的
fs.exists('./message2.txt', (exists) => {
console.log(exists); // false
});
6.3) 獲取文件或目錄的絕對路徑realpath和realpathSync方法
在fs模塊中,可以使用 realpath方法獲取一個文件或目錄的絕對路徑,該方法使用如下所示:
fs.realpath(path, [cache], callback);
cache 參數是可選的,path和callback是必須的。
path參數為需要查看的文件或目錄的完整路徑。
cache參數為一個對象,其中存放了一些預先指定的路徑。具體的百度下,這個參數用的不多。
callback是回調函數,該回調函數有2個參數,err參數值為獲取目錄的絕對路徑失敗的錯誤對象。resolvedPath參數值為獲取
到的文件或目錄的絕對路徑。
下面是一個簡單的demo,如下所示:
const fs = require('fs');
fs.realpath('./message.txt', (err, resolvedPath) => {
if (err) {
throw err;
} else {
console.log(resolvedPath);
}
});
執行如下所示:

6.4) 使用ReadStream對象讀取文件
在fs模塊中,可以使用createReadStream方法創建一個將文件內容讀取為流數據的ReadStream對象,該方法使用如下所示:
fs.createReadStream(path, [options]);
path 該參數用於指定需要被讀取的文件的完整路徑及文件名。
options為一個對象,它有如下屬性:
flags: 用於指定對該文件采取什么操作,默認值為 'r', 它的用法和readFile方法中的flags屬性一樣的。
encoding: 指定使用什么編碼來讀取該文件,可指定的值有 'utf8', 'ascii', 'base64'. 默認值為null.
start: 指定文件的開始讀取位置。
end: 指定文件的結束讀取位置。
還有很多其他的參數,這里不一一講解,可以自行百度下即可。
下面簡單的使用一個demo來了解下使用:如下代碼:
const fs = require('fs');
/*
一個漢字三個字節,message.txt的內容為:我喜愛編寫代碼
因此從第三個位置開始,到第十二個位置結束,因此數據應該為 喜愛編寫
*/
const options = {
start: 3,
end: 12
};
const file = fs.createReadStream('./message.txt', options);
file.on('open', (fd) => {
console.log('開始讀取文件');
});
file.on('data', (data) => {
console.log('讀取到的數據:' + data);
});
file.on('end', () => {
console.log('文件已全部讀取完畢');
});
file.on('close', () => {
console.log('文件被關閉');
});
file.on('error', (err) => {
console.log('讀取文件失敗');
});
如下圖所示:

我們可以使用 ReadStream對象的pause方法暫停data事件的觸發,同時也意味着停止文件的讀取操作。而已經被讀取到的操作系統緩存區中的數據也將被暫時保存在操作系統緩沖區中,在使用了pause方法暫停data事件的觸發之后,也可以使用ReadStream對象的resume方法恢復data事件的觸發,也就意味着可以繼續讀取文件的數據。
如下demo:
const fs = require('fs');
const readStream = fs.createReadStream('./message.txt');
readStream.pause();
readStream.on('data', (data) => {
console.log('獲取到的數據為:' +data);
});
setTimeout(() => {
readStream.resume();
}, 1000);
讀取過程中,斷聽了一秒后,繼續把數據讀出來了。
注意:寫入文件的方法是 WriteStream, 使用方式和讀方式類似,這里不多介紹。
