檔案系統簡單來說就是通過Node來作業系統中的檔案
使用檔案系統,需要先引入fs子產品,fs是核心子產品,直接引入不需要下載下傳
異步和同步
Node.js 檔案系統(fs 子產品)子產品中的方法均有異步和同步版本,例如讀取檔案内容的函數有異步的 fs.readFile() 和同步的 fs.readFileSync()。
異步的方法函數最後一個參數為回調函數,回調函數的第一個參數包含了錯誤資訊(error)。
建議大家使用異步方法,比起同步,異步方法性能更高,速度更快,而且沒有阻塞。
檔案的寫入
同步
writeFileSync()
将要寫入的檔案内容完整的讀入緩存區,然後一次性的将緩存區中的内容寫入都檔案中(一次全部傳完)
writeFileSync(file, data[, options])
使用同步的方式讀取資料,且讀取的内容通過傳回值擷取。
- file 要操作的檔案的路徑
- data 要寫入的資料
- options 選項,預設為null 也可直接傳入
。encoding
- encoding 編碼,預設為
utf8
- flag 辨別位,預設為
w
- mode 權限位,預設為
0o666
- encoding 編碼,預設為
//引入fs子產品
var fs = require("fs");
fs.writeFile(
"hello3.txt",
"這是通過writeFile寫入的内容",
{ flag: "a" },
function (err) {
if (!err) {
console.log("檔案寫入成功");
}
}
);
writeSync()
将需要寫入的資料寫入到一個記憶體緩存區,待緩存區寫滿後再将緩存區中的内容寫入到檔案中
1.打開檔案
fs.openSync(path, flags[, mode])
- path 要打開檔案的路徑
- flags 打開檔案要做的操作的類型
- r 隻讀的
- w 可寫的
- mode 設定檔案的操作權限,一般不傳
- 傳回值:該方法會傳回一個檔案的描述符作為結果,我們可以通過該描述符來對檔案進行各種操作
2.向檔案中寫入内容
fs.writeSync(fd, string[, position[, encoding]])
- fd 檔案的描述符,需要傳遞要寫入的檔案的描述符
- string 要寫入的内容
- position 寫入的起始位置
- encoding 寫入的編碼,預設utf-8
3.儲存并關閉檔案
fs.closeSync(fd)
- fd 要關閉的檔案的描述符
eg:
var fs = require("fs");
//打開檔案
var fd = fs.openSync("hello.txt", "r");
//向檔案中寫入内容
fs.writeSync(fd, "今天天氣真不錯~~~");
//關閉檔案
fs.closeSync(fd);
console.log("程式向下執行~~~");
異步
writeFile()
writeFile(file, data[, options], callback)
将要寫入的檔案内容完整的讀入緩存區,然後一次性的将緩存區中的内容寫入都檔案中(一次全部傳完,檔案過大就會影響效率)
- file 要操作的檔案的路徑
- data 要寫入的資料
- options 選項,可以對寫入進行一些設定
- callback 當寫入完成以後執行的函數
- flag
- r 隻讀
- w 可寫
- a 追加
- flag
const fs = require("fs");
fs.writeFile("2.txt", "Hello world", err => {
if (!err) {
fs.readFile("2.txt", "utf8", (err, data) => {
console.log(data); // Hello world
});
}
});
write()
将需要寫入的資料寫入到一個記憶體緩存區,待緩存區寫滿後再将緩存區中的内容寫入到檔案中(分批次,存滿一個傳一個)
1.打開檔案
fs.open(path, flags[, mode], callback)
- path:要打開檔案的路徑
- flags:打開檔案要做的操作的類型
- r 隻讀的
- w 可寫的
- mode:設定檔案的操作權限,一般不傳
- callback:err錯誤對象,如果沒有錯誤則為null
2.向檔案中寫入内容
fs.write(fd, string[, position[, encoding]], callback)
- fd 檔案的描述符,需要傳遞要寫入的檔案的描述符
- string 要寫入的内容
- position 寫入的起始位置
- encoding 寫入的編碼,預設utf-8
- callback:err錯誤對象,如果沒有錯誤則為null
3.儲存并關閉檔案
fs.close(fd, callback)
- fd 要關閉的檔案的描述符
eg:
//引入fs子產品
var fs = require("fs");
//打開檔案
fs.open("hello2.txt", "w", function (err, fd) {
//判斷是否出錯
if (!err) {
//如果沒有出錯,則對檔案進行寫入操作
fs.write(fd, "異步檔案的寫入", function (err) {
if (!err) {
console.log("寫入檔案成功");
}
//關閉檔案
fs.close(fd, function (err) {
if (!err) {
console.log("檔案關閉成功");
}
});
});
} else {
console.log(err);
}
});
console.log("程式向下執行")
//異步執行不會阻塞,是以最下面的 ”程式向下執行“ 最先輸出
/*輸出為:
程式向下執行
寫入檔案成功
檔案關閉成功
*/
讀取檔案
同步
readFileSync()
readFileSync(path[, options])
- path 要讀取的檔案的路徑
- options 讀取的選項,預設值為
,其中有null
(編碼,預設為encoding
)和null
(辨別位,預設為flag
),也可直接傳入r
;encoding
若現在有一個檔案名為
1.txt
,内容為 “Hello”,現在使用
readFileSync
讀取。
const fs = require("fs");
let buf = fs.readFileSync("1.txt");
let data = fs.readFileSync("1.txt", "utf8");
console.log(buf); // <Buffer 48 65 6c 6c 6f>
console.log(data); // Hello
readSync()
readSync(fd, buffer, offset, length, position)
方法将傳回一個 bytesRead (讀取的位元組數)
- fd:檔案描述符,需要先使用 open 打開;
- buffer:存儲将要寫入檔案資料的 Buffer;
- offset:整數,從 Buffer 讀取資料的初始位置;
- length:整數,讀取 Buffer 資料的位元組數;
- position:整數,寫入檔案初始位置;
下面讀取一個
6.txt
檔案,内容為 “你好”。
var fs = require("fs");
let buf = Buffer.alloc(6);
fs.open("6.txt", "r", function (err, fd) {
if (err) {
console.error(err);
return;
}
var bytesRead = fs.readSync(fd, buf, 0, 6, 0);
console.log(bytesRead);
console.log(buf);
console.log(buf.toString());
});
// 6
// <Buffer e4 bd a0 e5 a5 bd>
// 你好
異步
readFile()
readFile(path[, options], callback)
- 前兩個參數同上相同
- callback回調函數,通過回調函數将讀取到内容傳回(err , data)
- err 錯誤對象
- data 讀取到的資料,會傳回一個Buffer
依然讀取
1.txt
檔案:
const fs = require("fs");
fs.readFile("1.txt", "utf8", (err, data) => {
console.log(err); // null
console.log(data); // Hello
});
read()
read
方法與
readFile
不同,一般針對于檔案太大,無法一次性讀取全部内容到緩存中或檔案大小未知的情況,都是多次讀取到 Buffer 中。
read(buffer, offset, length, position)
- fd:檔案描述符,需要先使用 open 打開;
- buffer:存儲将要寫入檔案資料的 Buffer;
- offset:整數,從 Buffer 讀取資料的初始位置;
- length:整數,讀取 Buffer 資料的位元組數;
- position:整數,寫入檔案初始位置;
- callback:回調函數,寫入完成後執行。
- err(錯誤)
- bytesWritten(實際寫入的位元組數)
- buffer(被讀取的緩存區對象)
下面讀取一個
6.txt
檔案,内容為 “你好”。
const fs = require("fs");
let buf = Buffer.alloc(6);
// 打開檔案
fs.open("6.txt", "r", (err, fd) => {
// 讀取檔案
fs.read(fd, buf, 0, 3, 0, (err, bytesRead, buffer) => {
console.log(bytesRead);
console.log(buffer);
// 繼續讀取
fs.read(fd, buf, 3, 3, 3, (err, bytesRead, buffer) => {
console.log(bytesRead);
console.log(buffer);
console.log(buffer.toString());
});
});
});
// 3
// <Buffer e4 bd a0 00 00 00>
// 3
// <Buffer e4 bd a0 e5 a5 bd>
// 你好
流式檔案的寫入 —— 推薦
同步、異步、簡單檔案的寫入都不适合大檔案的寫入,性能較差,容易導緻記憶體溢出
fs.createWriteStream(path[, options])
- path,檔案路徑
- options 配置的參數
可以通過監聽流的open和close事件來監聽流的打開和關閉
var fs = require("fs");
//流式檔案寫入
//建立一個可寫流
var ws = fs.createWriteStream("hello3.txt");
//可以通過監聽流的open和close事件來監聽流的打開和關閉
/*
on(事件字元串,回調函數)
- 可以為對象綁定一個事件
once(事件字元串,回調函數)
- 可以為對象綁定一個一次性的事件,該事件将會在觸發一次以後自動失效
**/
ws.once("open",function () {
console.log("流打開了~~~");
});
ws.once("close",function () {
console.log("流關閉了~~~");
});
//通過ws向檔案中輸出内容
ws.write("通過可寫流寫入檔案的内容");
ws.write("今天天氣真不錯");
ws.write("鋤禾日當午");
ws.write("紅掌撥清清");
ws.write("清清真漂亮");
//關閉流
ws.end();
流式檔案的讀取
fs.createReadStream(path[, options])
流式檔案讀取也适用于一些比較大的檔案,可以分多次将檔案讀取到記憶體中
- path,檔案路徑
- options 配置的參數
var fs = require("fs");
//建立一個可讀流
var rs = fs.createReadStream("hello3.txt");
//建立一個可寫流
var ws = fs.createWriteStream("hello5.txt");
//監聽流的開啟和關閉
rs.once("open", function () {
console.log("可讀流打開了~~");
});
rs.once("close", function () {
console.log("可讀流關閉了~~");
});
ws.once("open", function () {
console.log("可寫流打開了~~");
});
ws.once("close", function () {
console.log("可寫流關閉了~~");
ws.end();
});
// pipe()可以将可讀流中的内容,直接輸出到可寫流中
rs.pipe(ws);