2012-10-29 19 views
6

我試圖使讀取文件參數。當我做這個代碼:nodejs中使用fs.stat的問題

var fs = require('fs'), 
    size = new Object(); 
fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
     } 
     }) 
    console.log(size); 

它`好吧,當我試圖使用功能:

var fs = require('fs'), 
    size = new Object(); 
function writeinfile(file){ 
    fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
     } 
     }) 
    console.log(size.size); 
} 
writeinfile('error.log'); 

它`不行。你能幫我做一下變體2的工作嗎?

回答

0

您的代碼有幾種觀察結果。但是,我們在這裏學習:

  1. 確保把回調內部console.log(即略低於size=stats),這樣你可以得到你所需要的信息,該函數的任務後。

  2. 添加此行以上if (!err)

    如果(ERR)的console.log(ERR);

您將看到以下

{ [Error: ENOENT, stat 'error.log'] errno: 34, code: 'ENOENT', path: 'error.log' } 

這意味着對路徑的錯誤。輕鬆修復:使用fs.exists()檢查文件是否存在,和/或始終確保以__dirname作爲文件名的前綴。

  1. 最後一行談到writeinfile,但fs.stats爲您提供了有關文件的信息......我認爲,一個更好的功能將是fs.write()這個任務。
+0

我想在文件中寫入信息,重命名文件,當它達到所需的大小(以fs.rename)和寫在fs.write新的文件信息。我計劃在變量「size」中使用fs.stat來獲取文件大小,並使用if(size <= 238084)(fs.rename(...))else fs.write(....)。 – IIEIIEJI

12

您的console.log超出了您的fs.stat回調。固定它:

var fs = require('fs'), 
    size = new Object(); 
function writeinfile(file){ 
    fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
      console.log(size.size); 
     } 
     }) 

} 
writeinfile('error.log'); 

我也改寫你的代碼中的Node.js使用更地道(多見)語法:

var fs = require('fs'); 

function writeinfile (file, cb) { 
    fs.stat(file, function(err,stats){ 
    if(err) return cb(err); 
    cb(null, stats.size); 
    }) 
} 

writeinfile('error.log', function(err, size) { 
    if(err) { 
    console.log(err); 
    return; 
    } 
    console.log('The size of the file is ' + size); 
}); 

正如赫爾曼在他的回答中提到,這將是一個很好的如果您不寫入文件,可以選擇更好的函數名稱。

最後,在Javascript中,您可以使用{}作爲new Object()的快捷方式。例如:var size = {};

1

在您的示例中,由於fs.stat()的異步性質,在console.log(size)運行時期望設置size的值是不正確的。

下面是實際發生的情況,依次是:

  1. 您所需要的fs模塊和實例化一個新的size對象。
  2. 你在未來調用fs.stat(路徑,CB)與回調
  3. 你打電話的console.log(大小)
  4. 然後,在某些時候,FS。stat()調用您的回調

事情按此順序發生,因爲由於文件io的異步性質,無法事先預測進行所需的文件系統調用所需的時間。取決於光盤目前在做什麼,它可能需要4到4000ms或更長的時間。

這就是爲什麼我們依靠回調,因爲他們保證,當他們已應用於功能齊全,或在這種情況下,當文件路徑的地位已被確定發生。

請不要感覺不好。這是一個錯誤每個人都在異步編程時,編程節點時,最頭疼的概念。

+0

+1最初的回調令人沮喪! –

1

你需要把執行console.log(size.size);裏面的回調函數,但我想我需要更好地解釋。

您需要了解異步調用和Node.js的事件循環。創建Node.js是爲了以更好的方式對資源進行paralelize,以便爲比CPU密集型的IO密集型(比如Web服務器)更多的問題創建線程。這個想法是,使用IO的非阻塞調用的邏輯單線程比創建多線程和調用塊函數使用IO更好。

如果在其他語言程序,你應該熟悉你的算法的sinchronous版本:

var fs = require('fs'), 
size = new Object(); 
function writeinfile(file) { 
    var stats = fs.statSync(path); 
    size = stats.size; 
    console.log(size); 
}; 

writeinfile('error.log'); 

這是Node.js的代碼,但是這不是節點的方式。當您調用statSync()時,您的腳本塊將等待從磁盤讀取統計信息。

但是,當你只使用fs.stat(),你的程序將運行直到代碼結束,而磁盤讀取。所有的下一行將在程序實現事件循環之前運行。只要統計數據準備好並且程序運行到結束時,事件循環將調用您在fs.stat(callback)調用中通過參數傳遞的回調函數。

因此,在你的代碼中,你調用一個stat(assynchronous版本),並嘗試使用尚未就緒的值,因爲在調用回調之前總會在assynchronous調用之後運行代碼。

的第一個版本,我認爲工作只是因爲你應該在解釋手動typping的代碼,因此,該程序實現事件循環需要鍵入下一行的時間是足夠多。在這種模式下,每次輸入一個命令,按回車鍵,那個代碼就會運行,也就是說,你會得到一個返回值,事件循環中的事件將被調用。