1. 程式人生 > >node 操作檔案流 fs 同步與非同步 流式檔案的寫入與讀取

node 操作檔案流 fs 同步與非同步 流式檔案的寫入與讀取

fs

fs ( File System ) 檔案系統

在node中通過fs模組來和系統中的檔案進行互動
通過fs模組可以對磁碟中的檔案做各種增刪改查的操作

    寫入檔案
        1.同步寫入
        2.非同步寫入
        3.簡單寫入
        4.流式寫入

    讀取檔案

        在fs模組中所有的方法都有兩個版本
            不帶sync的,非同步方法
            帶sync的,同步方法

1、同步寫入

**1.開啟要寫入的檔案**
    fs.openSync(path, flags[, mode])
    該方法用來開啟一個檔案
    引數:
    path:路徑,要開啟檔案的路徑
    flags:操作的型別,要對檔案做什麼操作
    需要字串作為引數
    "w" 寫
    "r" 讀
    "a" 追加
    mode:可選引數,一般不傳,用來設定檔案的許可權

    返回值:
    fd 檔案的描述符

2.寫入並儲存
    fs.writeSync(fd, string[, position[, encoding]])
    該方法用於向檔案中寫入內容
    引數:
    fd: 檔案的描述符,需要指定要寫入檔案的描述符
    string: 要寫入的內容
    position: 開始寫入的位置
    encoding: 寫入內容的字元編碼,預設utf-8


3.關閉檔案
    fs.closeSync(fd):: 該方法用來關閉檔案
    引數:
    fd 檔案的描述符

例項
    //引入fs模組
    var fs=require('fs');
    var fd=fs.openSync('gzl.txt','w');
    fs.writeSync(fd,'1111',10,'utf-8');
    fs.closeSync(fd);

2.簡單檔案的寫入

簡單檔案寫入
     fs.writeFile(file, data[, options], callback)
     fs.writeFileSync(file, data[, options])
 - 引數:
        file 要寫入的檔案的路徑
        data 要寫入的內容
        options 配置物件(可選)
            encoding 編碼 預設 utf8
            flag  操作型別  預設 w
            mode  檔案的許可權 預設666,一般不需要傳
            callback 回撥函式,寫入完成後會呼叫該函式

3.非同步寫入

1.開啟檔案
    fs.open(path, flags[, mode], callback)
    引數:callback
    回撥函式,會在檔案開啟以後執行
    回撥函式中會有兩個引數:
    err: 錯誤資訊,如果操作過程中出現了錯誤,則該物件存在,如果沒有出現錯誤,則該引數的值為null
    錯誤優先
    fd: 檔案的描述符

2.寫入檔案
    fs.write(fd, string[, position[, encoding]], callback)
    callback 回撥函式會在寫入完畢以後執行
    引數:
    err 錯誤物件
    byte 寫入的位元組數
    data 寫入的資料

3.關閉檔案
    fs.close(fd, callback)
非同步寫入的相關程式碼:::
var fs=require('fs');
fs.open('gzl.txt','a',function (err,fd) {
    if (!err){
        fs.write(fd,'ffffff',10,function (err,bite,data) {
          if (!err){
              console.log('檔案寫入成功');
          };
          fs.close(fd,function (err) {
            if (!err){
                console.log('檔案已關閉');
            };
          });
        });
    };
});

4.流式檔案的寫入與讀取

流式檔案寫入
   其他的檔案的寫入方式都是一次性將一個內容寫入到檔案中的,
   如果檔案太大了則會導致執行速度過慢,會嚴重影響程式的效能
   流式檔案寫入適合較大的檔案寫入,可以分多次將多個內容輸出到檔案中
相關程式碼:
//建立一個可寫流(WriteStream)
var ws = fs.createWriteStream("hello3.txt");

//為流繫結一個open和close事件,來監聽流是否開啟和關閉
ws.once("open",function () {
    console.log("流打開了~~~");
});

ws.once("close",function () {
    console.log("流關閉了~~~");
});

//通過可寫流向檔案中輸出內容
ws.write("O(∩_∩)O哈哈~");
ws.write("O(∩_∩)O~");

//關閉流
ws.end();
流式檔案讀取
   適合較大的檔案讀取
相關程式碼:
//建立一個可讀流
var rs = fs.createReadStream("C:\\Users\\lilichao\\Desktop\\筆記.mp3");
//建立一個可寫流
var ws = fs.createWriteStream("a.mp3");

//監聽流的狀態
rs.once("open",function () {
    console.log("可讀流已經開啟");
});

rs.once("close",function () {
    console.log("可讀流已經關閉");
    //關閉可寫流
    ws.end();
});

ws.once("open",function () {
    console.log("~~~~可寫流已經開啟");
});

ws.once("close",function () {
    console.log("~~~~可寫流已經關閉");
});

//要讀取一個可讀流中的資料,必須要給該流繫結一個data事件
//繫結data事件後,流會自動讀取資料,資料讀取完畢以後,流會自動關閉
//讀取到的資料會通過回撥函式的引數的形式返回
rs.on("data",function (data) {
    //console.log(data.length);
    //將資料線寫入到可寫流中
    ws.write(data);

});


簡單方法::
//建立一個可讀流
var rs = fs.createReadStream("C:\\Users\\lilichao\\Desktop\\筆記.mp3");
//建立一個可寫流
var ws = fs.createWriteStream("b.mp3");
//將可讀流中的資料寫入到可寫流中
rs.pipe(ws);

5.其他讀取檔案

相關程式碼:
/*
 驗證路徑是否存在
     fs.existsSync(path)
 獲取檔案資訊
     fs.stat(path, callback)
     fs.statSync(path)
 刪除檔案
     fs.unlink(path, callback)
     fs.unlinkSync(path)

 */

var result = fs.existsSync("ab.jpg");

//console.log(result);


fs.stat("a.jpg", function (err , stats) {
    if(!err){
        //stats 是一個物件,在該物件中儲存了當前檔案的狀態資訊
        /*
            通過該物件可以獲取檔案的狀態
                stats.size 獲取檔案的大小
                stats.isFile() 是否是檔案
                stats.isDirectory()是否是目錄
         */
        //console.log(stats.isDirectory());
    }
});

//刪除檔案
//fs.unlinkSync("hello.txt");

/*
 列出檔案
     fs.readdir(path[, options], callback)
     fs.readdirSync(path[, options])
 截斷檔案
     fs.truncate(path, len, callback)
     fs.truncateSync(path, len)
 建立目錄
     fs.mkdir(path[, mode], callback)
     fs.mkdirSync(path[, mode])

 */

/*
fs.readdir(".",function (err , files) {
    if(!err){
        //files是一個儲存了目錄下檔案(夾)名字的string陣列
        console.log(files[0]);
    }
});*/

//截斷檔案 將檔案截斷成指定的大小,會丟失資料
//fs.truncateSync("hello2.txt",10);

//建立目錄
//fs.mkdir("hello");

/*
刪除目錄
 fs.rmdir(path, callback)
 fs.rmdirSync(path)
重新命名檔案和目錄
 fs.rename(oldPath, newPath, callback)
 fs.renameSync(oldPath, newPath)
 - 通過該方法也可以實現剪下的功能

監視檔案更改寫入
    fs.watchFile(filename[, options], listener)
        - 引數:
    filename 檔名
    options 配置物件
    listener 回撥函式,當前檔案發生變化時,該函式將會執行
        - curr 表示檔案現在的狀態
        - prev 表示檔案修改前的狀態
            - 這兩個物件都是stats物件

*/

//fs.rmdir("hello");

/*fs.rename("b.mp3","C:\\Users\\lilichao\\Desktop\\b.mp3",function (err) {
    if(!err){
        console.log("修改成功");
    }
});*/

fs.watchFile("hello2.txt",{interval:1000},function (curr,prev) {
    console.log("當前檔案的大小為: "+curr.size);
    console.log("修改前檔案的大小為: "+prev.size);
});