在前面stteam流裡其實已經搞過Node.js的檔案讀寫,讀寫是目的,流是實作方式。
異步和同步
Node.js 檔案系統(fs 子產品)子產品中的方法均有異步和同步版本,例如讀取檔案内容的函數有異步的 fs.readFile() 和同步的 fs.readFileSync()。
異步的方法函數最後一個參數為回調函數,回調函數的第一個參數包含了錯誤資訊(error)。
異步方法,相對而言,性能更高,速度更快,而且沒有阻塞,使用的要多一些。
執行個體
建立input.txt,随便輸點什麼都行。
inCompare.js:
var fs = require("fs");
// 執行前建立一個空的 /test 目錄
console.log("準備删除目錄 ../test/temp");
fs.rmdir("../test/temp",function(err){
if (err) {
return console.error(err);
}
console.log("讀取 /tmp 目錄");
fs.readdir("../test/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
執行:
打開檔案
文法:
fs.open(path, flags[, mode], callback)
參數:
參數使用說明如下:
path - 檔案的路徑。
flags - 檔案打開的行為。具體值詳見下文。
mode - 設定檔案模式(權限),檔案建立預設權限為 0666(可讀,可寫)。
callback - 回調函數,帶有兩個參數如:callback(err, fd)。
flags 參數可以是以下值:
flag | 描述 |
r | 以讀取模式打開檔案。如果檔案不存在抛出異常。 |
r+ | 以讀寫模式打開檔案。如果檔案不存在抛出異常。 |
rs | 以同步的方式讀取檔案。 |
rs+ | 以同步的方式讀取和寫入檔案。 |
w | 以寫入模式打開檔案,如果檔案不存在則建立。 |
wx | 類似 ‘w’,但是如果檔案路徑存在,則檔案寫入失敗。 |
w+ | 以讀寫模式打開檔案,如果檔案不存在則建立。 |
wx+ | 類似 ‘w+’, 但是如果檔案路徑存在,則檔案讀寫失敗。 |
a | 以追加模式打開檔案,如果檔案不存在則建立。 |
ax | 類似 ‘a’, 但是如果檔案路徑存在,則檔案追加失敗。 |
a+ | 以讀取追加模式打開檔案,如果檔案不存在則建立。 |
ax+ | 類似 ‘a+’, 但是如果檔案路徑存在,則檔案讀取追加失敗。 |
執行個體:
fileInput.js,從input.txt中讀取資料:
var fs = require("fs");
// 異步打開檔案
console.log("準備打開檔案!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("檔案打開成功!");
});
運作:
擷取檔案資訊
異步擷取檔案資訊:
fs.stat(path, callback)
path - 檔案路徑。
callback - 回調函數,帶有兩個參數如:(err, stats), stats 是 fs.Stats 對象。
fs.stat(path)執行後,會将stats類的執行個體傳回給其回調函數。可以通過stats類中的提供方法判斷檔案的相關屬性。
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。 |
fileStats.js,擷取input.txt檔案的相應資訊:
var fs = require("fs");
console.log("準備打開檔案!");
fs.stat('input.txt', function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("讀取檔案資訊成功!");
// 檢測檔案類型
console.log("是否為檔案(isFile) ? " + stats.isFile());
console.log("是否為目錄(isDirectory) ? " + stats.isDirectory());
});
寫入檔案
fs.writeFile(file, data[, options], callback)
file - 檔案名或檔案描述符。
data - 要寫入檔案的資料,可以是 String(字元串) 或 Buffer(緩沖) 對象。
options - 該參數是一個對象,包含 {encoding, mode, flag}。預設編碼為 utf8, 模式為 0666 , flag 為 ‘w’
callback - 回調函數,回調函數隻包含錯誤資訊參數(err),在寫入失敗時傳回。
fileOutput.js,向input.txt中寫入資料:
var fs = require("fs");
console.log("準備寫入檔案");
fs.writeFile('input.txt', '我是通 過fs.writeFile 寫入檔案的内容', function(err) {
if (err) {
return console.error(err);
}
console.log("資料寫入成功!");
console.log("--------我是分割線-------------")
console.log("讀取寫入的資料!");
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("異步讀取檔案資料: " + data.toString());
});
});
讀取檔案
fs.read(fd, buffer, offset, length, position, callback)
fd - 通過 fs.open() 方法傳回的檔案描述符。
buffer - 資料寫入的緩沖區。
offset - 緩沖區寫入的寫入偏移量。
length - 要從檔案中讀取的位元組數。
position - 檔案讀取的起始位置,如果 position 的值為 null,則會從目前檔案指針的位置讀取。
callback - 回調函數,有三個參數err, bytesRead, buffer,err 為錯誤資訊, bytesRead 表示讀取的位元組數,buffer 為緩沖區對象。
fileRead.js,從input…txt中讀取資料:
var fs = require("fs");
var buf = new Buffer.alloc(1024);
console.log("準備打開已存在的檔案!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("檔案打開成功!");
console.log("準備讀取檔案:");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
console.log(bytes + " 位元組被讀取");
// 僅輸出讀取的位元組
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
});
});
關閉檔案
fs.close(fd, callback)
該方法使用了檔案描述符來讀取檔案。
參數
callback - 回調函數,沒有參數。
fileClose.js:
var fs = require("fs");
var buf = new Buffer.alloc(1024);
console.log("準備打開檔案!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("檔案打開成功!");
console.log("準備讀取檔案!");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
// 僅輸出讀取的位元組
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
// 關閉檔案
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("檔案關閉成功");
});
});
});
截取檔案
fs.ftruncate(fd, len, callback)
len - 檔案内容截取的長度。
fileCat.js,根據長度截取Input.txt中讀取的資料:
var buf = new Buffer.alloc(1024);
console.log("準備打開檔案!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("檔案打開成功!");
console.log("截取10位元組内的檔案内容,超出部分将被去除。");
// 截取檔案
fs.ftruncate(fd, 10, function(err){
if (err){
console.log(err);
}
console.log("檔案截取成功。");
console.log("讀取相同的檔案");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
// 僅輸出讀取的位元組
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
// 關閉檔案
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("檔案關閉成功!");
});
});
});
});
删除檔案
fs.unlink(path, callback)
執行個體:fileDelete.js,删除input.txt:
var fs = require("fs");
console.log("準備删除檔案!");
fs.unlink('input.txt', function(err) {
if (err) {
return console.error(err);
}
console.log("檔案删除成功!");
});
建立目錄
fs.mkdir(path[, options], callback)
options 參數可以是:
recursive - 是否以遞歸的方式建立目錄,預設為 false。
mode - 設定目錄權限,預設為 0777。
creatPath.js:
var fs = require("fs");
// tmp 目錄必須存在
console.log("建立目錄 /test/");
fs.mkdir("/test/",function(err){
if (err) {
return console.error(err);
}
console.log("目錄建立成功。");
});
讀取目錄
fs.readdir(path, callback)
callback - 回調函數,回調函數帶有兩個參數err, files,err 為錯誤資訊,files 為 目錄下的檔案數組清單。
readPath.js:
var fs = require("fs");
console.log("檢視 /project 目錄");
fs.readdir("/project/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
删除目錄
fs.rmdir(path, callback)
deletePath.js:
var fs = require("fs");
// 執行前建立一個空的 /test 目錄
console.log("準備删除目錄 ../test/temp");
fs.rmdir("../test/temp",function(err){
if (err) {
return console.error(err);
}
console.log("讀取 /tmp 目錄");
fs.readdir("../test/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
路徑要對,路徑下要沒有檔案,不然會報錯。
運作:
官方file 子產品API:
https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback參考:
【1】、
https://www.runoob.com/nodejs/nodejs-fs.html【2】、
https://www.w3cschool.cn/nodejs/nodejs-global-object.html【3】、
http://how2j.cn/k/nodejs/nodejs-file/1764.html#nowhere