2012-04-30 178 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的功能需要一个缓冲区而不是一个字符串。我会尝试的。 –