04小白學nodejs 檔案寫入

junwind發表於2021-05-25

一個伺服器的本質就是讀寫檔案內容,提供檔案內容給遠端的客戶端
node使用fs模組與檔案做互動,fs是核心模組,無需下載,直接引入即可
檔案寫入的幾種方式:同步,非同步,簡單方法,流式寫入

先說一下同步和非同步:

  • node中一般的API方法都有兩種方式,同步和非同步;
  • 同步會阻塞程式的執行,也就是調方法後,得等待方法得返回後,才能繼續向下執行;
  • 非同步呼叫是不等返回,先執行後面的程式碼,等有返回了,觸發回撥函式,返回的資料作為引數,傳給回撥;

同步寫入

var fs = require('fs');

//1. 開啟檔案  fs.openSync(path, flags[, mode])  
var fd = fs.openSync("hello.txt", "w");//該方法會返回一個檔案的資源描述符,可以通過該描述符來對檔案進行各種操作
// console.log(fd);

//2. 寫入內容  fs.writeSync(fd, buffer[, offset[, length[, position]]])
fs.writeSync(fd, "content...")

// 開啟檔案,寫入資料後,此時開啟的資源還在記憶體中,沒關閉 會一直佔用記憶體空間
//3. 關閉檔案
fs.closeSync(fd)  

非同步寫入

非同步不需要等待返回,返回的物件作為引數傳給回撥函式

var fs = require('fs');

//開啟一個檔案 
fs.open("hello.txt", 'w', function(err, fd){//交給後臺的IO執行緒池執行,不阻塞,後續的程式碼繼續執行,當後臺IO執行緒開啟檔案後,返回結果到回撥函式中
    // console.log(arguments);
    if(!err) {
        //console.log(fd);
        //如果沒有出錯,則對檔案進行寫入操作
        fs.write(fd, "這是非同步寫入的內容", function (err) {
            if(!err) {
                console.log('寫入成功');
            }

            //關閉檔案
            fs.close(fd, function(err){
                if(!err) {
                    console.log("檔案已關閉");
                }
            })
        })
    } else {
        console.log(err);
    }
});

console.log("程式是非同步的");

簡單方式寫入

fs.writeFile(file, data[, options], callback)
fs.writeFileSync()

var fs = require('fs');
fs.writeFile('hello.txt', 'haaaaaaaa', {flag:"a"}, function(err){
    if(!err) {
        console.log("寫入成功...");
    } else {
        console.log(err);
    }
});

流式寫入

  • 讀寫檔案,就像從一個池子裡往另一個池子裡送水
  • 前面的非同步,同步檔案寫入,都是一次性全部寫入內容到一個檔案中,但是有一個問題,我寫入之前,得把所有得內容全都載入到記憶體中,然後再一次性寫入,假如檔案特別大,則記憶體無法一下子都快取 (記憶體溢位)
  • 所以無論是同步,還是非同步,都不適合大檔案得寫入
var fs = require('fs');

//建立一個可寫流
var ws = fs.createWriteStream('hello.txt');//ws相當於連線到hello.txt得水管子

//通過ws這跟水管向hello.txt檔案中輸出內容
// ws.write("通過可寫流寫入檔案得內容");
// ws.write("通過可寫流寫入檔案得內容");
// ws.write("通過可寫流寫入檔案得內容");
// ws.write("通過可寫流寫入檔案得內容");
// ws.write("通過可寫流寫入檔案得內容");
//流式寫入,可以分多次把一個資料寫入檔案中,此時流並沒有關閉,還可以繼續寫,當然也在繼續佔用系統資源
//對於流,需要對它得開啟(open)和關閉(close)進行監聽

//監聽流的open事件
/*ws.on('open', function() {
    console.log('流開啟了...');
});*/
//但是這裡要注意,open事件只會觸發一次(即open是一個一次性的事件),即流只會開啟一次,所以這裡用once繫結更好
//因為on繫結的函式,執行後,還依舊存在,而這裡的開啟僅是一次的動作,所以僅監聽執行一次即可
//open開啟監聽執行函式完畢後,即可銷燬,不用再次監聽執行了。
//on一般是繫結一個長期有效的事件
//once(事件字串,回撥函式)   可以為物件繫結一個一次性的事件,該事件將會在觸發一次以後,自動失效

ws.once('open', function(){
    console.log('流開啟了...');
});
ws.once('close', function(){
    console.log('流關閉了...');
});

ws.write("1111111");
ws.write("2222222");
ws.write("3333333");

ws.end();//結束流,這裡最好是不要使用ws.close();  其實end就是拔水管送水的這頭,即都送給水管了,就可以拔了,存在水管中的水還是可以到接收池子裡
//close相當於拔接收端,假如此時水管中還有水,則丟失了;可能會導致資料丟失
本作品採用《CC 協議》,轉載必須註明作者和本文連結
六月的風

相關文章