2012-04-30 177 views
2

我使用這個異步遞歸函數遍歷目錄的文件和文件夾,當找到.css文件時,我將數據追加到名爲'common.css'的文件中。異步追加數據到文件

var walk = function(dir, done) { 
var results = []; 

fs.readdir(dir, function(err, list) { 
     if (err) return done(err); 
     var pending = list.length; 
     if (!pending) return done(null); 
     list.forEach(function(file) { 
      file = dir + '/' + file; 
      fs.stat(file, function(err, stat) { 
       if (stat && stat.isDirectory()) { 
        minimizer(file, function(err, res) { 
          results = results.concat(res); 
          if (!--pending) done(null); 
        }); 
       } else if(file) { 
        fs.open('common.css', 'a', 666, function(err, id) { 
         fs.write(id, 'hello', null, 'utf8', function(){ 
          fs.close(id, function(){ 
            console.log('file closed'); 
          }); 
         }); 
        }); 
       } 
       if (!--pending) done(null); 
      }); 
     }); 
}); } 

問題是,我覺得有些時候,函數的幾個實例同時寫入文件,這是異步的。有沒有什麼辦法可以控制這種流量並排列寫作任務?

此代碼的目的是合併目錄中找到的.css文件。我不能在這個項目中使用外部工具。

編輯回答:那麼,爲了這個目的,我可以收集所有.css文件的路徑,我想要合併,並且在我擁有它們之後,調用syncronous函數來編寫它們。

這就是

VAR的結果= []

是有什麼。我剛剛意識到這一點。

+0

在這個例子中你開擴,並在該目錄中common.css書面方式招呼每一個文件,所以如果你有3個文件,你會寫「hellohellohello」。這是你的真實代碼嗎?爲此目的,您可以獲得文件數量,然後只打開和寫入一次「hello」N次。 –

回答

0

那麼,我最終使用串行遞歸函數用於相同的目的。它解決了這個問題。在從node.js fs.readdir recursive directory search

var fs = require('fs'); 
var walk = function(dir, done) { 
    var results = []; 
    fs.readdir(dir, function(err, list) { 
    if (err) return done(err); 
    var i = 0; 
    (function next() { 
     var file = list[i++]; 
     if (!file) return done(null, results); 
     file = dir + '/' + file; 
     fs.stat(file, function(err, stat) { 
     if (stat && stat.isDirectory()) { 
      walk(file, function(err, res) { 
      results = results.concat(res); 
      next(); 
      }); 
     } else { 
      results.push(file); 
      next(); 
     } 
     }); 
    })(); 
    }); 
}; 

採取用戶「chjj」的答案謝謝大家的建議:)

0

我的建議是,如果您將其作爲獨立應用程序來執行此操作,而不是某個更大的應用程序的一部分,則可以將所有css文件寫入console.log,並通過「node combine.js> combined.cc 」。從我所見過的使用FileStreams和console.log,它不會混雜寫入。

+0

那麼,爲了這個目的,我可以收集所有想要合併的.css文件的路徑,並且在我擁有它們之後,調用syncronous函數來編寫它們.-謝謝您的回答,無論如何user1291492!如果這不起作用,我會看到你的建議:) 這是一個非常大的Web應用程序。 –

+0

您是否有任何建議知道所有函數調用何時結束?確切知道何時找到最後一個文件。 –

+0

在完成搜索所有目錄之前,您無法知道是否找到了最後一個文件。你怎麼知道你是否搜索過所有的目錄?在節點的回調框架中很難知道這個 – ControlAltDel

1

我認爲我會考慮使用類似的async.js庫,對確保事情按正確的順序發生,包括async.forEachSeries(arr, eachFn, doneFn)

0

你可以在開始打開common.css並保持的文件描述符的能力,每當遇到CSS文件時請致電fs.write(id, ...)。這不是每次重新打開common.css的當前方法。

在您的代碼中,看起來您正在將hello寫入該文件。如果這是真的,或者你寫的東西相對較短(通常是512或4096字節,取決於平臺),所有附加到common.css將是原子的,所以不同的異步函數同時寫入不會干擾每個其他。

+0

我試過了你的建議,但common.css沒有被正確寫入。我設法創建了一個syncronous循環來完成這個任務,所以問題不再是多個實例同時被寫入。這可能是關於附加功能。我一定不能很好地工作。我看到fs.write(); node.js的功能需要一個緩衝區而不是一個字符串。我會嘗試的。 –