2013-01-15 23 views
1

我想從路徑獲取文件和目錄的所有名稱,並將它們識別爲文件和目錄。但是當我運行我的代碼有時它的工作和somentimes它顯示目錄是文件。這裏是我意識到,當我data.forEach循環減慢(使用的console.log(東西)它工作得更好(少小姐)代碼節點isDirectory()無法正常工作或者我不知所措

socket.on('data',function(path){ 
    fs.readdir('path',function(err, data) { 
    var filestatus=[]; 
    var z=0; 
    var i=data.length-1; 

    data.forEach(function(file){ 
     fs.stat(file, function(err, stats) { 
     filestatus[z]=stats.isDirectory() 
     if (z==i){ 
      socket.emit('backinfo',{names:data,status:filestatus}); 
     } 
     z++; 
     }) 
    }) 
    }) 
}) 

在測試過程中,這是奇怪的。

+0

1.注意'FS .readdir的結果只是名字,而不是完整的程序。 2.在檢查與「i」相等之前是否應該增加「z」? 3.查看[async](https://github.com/caolan/async)。 – elmigranto

+0

您不會在fs.stat回調中檢查'err',正如elmigranto指出的那樣,'file'只是文件名,而不是路徑,所以在調用'fs時需要在這些名稱前加上'path'。 stat'。 – JohnnyHK

回答

0

這是大約96%不正確的,謝謝JohnnyHK指出我的錯誤,請看下面的真實問題/解決方案的評論。

因爲fs.stat()函數調用是異步的,所以對filestatus數組重疊,您應該使用async建議使用elmigranto庫,或切換到使用fs.statSync。

更多細節上發生了什麼:

當你調用fs.stat(),它基本上會在後臺運行,然後立即去到的下一行代碼。當它獲得了文件的詳細信息後,它會調用回調函數,該函數在代碼中是將信息添加到filestatus數組的函數。

由於fs.stat()在返回之前沒有等待,您的程序正在快速通過數據數組,並且多個回調函數正在同時運行並且導致問題,因爲z變量沒有立即增加,所以

filestatus[z]=stats.isDirectory() 

可能會在z遞增之前被不同的回調多次執行。

希望有道理!

+0

是的,它是有道理的 - 它正是我的想法,但不確定。謝謝你的回答。 – Kriss

+2

這不是一個正確的答案。 Node.js是單線程的,因此您的代碼中沒有任何事情會同時發生。在下一個回調發生之前,每個回調都會運行完成,因此'z'的遞增很好。 – JohnnyHK

+1

@JohnnyHK狗屎,你完全正確。不過,我認爲Kriss認爲名稱和狀態數組的順序是相同的,這不會是真實的,因爲回調的順序並不固定。 所以我完全錯誤的是同時執行多個回調,但回調是亂序執行的,這意味着filestatus數組將不匹配名稱數組。對? – matthewtole

0

您使用在聲明的NodeJS,如果打開for語句來遞歸函數這將工作,請參閱幫助附帶的代碼


function load_Files(pat,callback) { 
console.log("Searching Path is: "+ph); 
fs.readdir(pat,(err,files)=> 
{ 
    if(err) 
    { 
     callback(err); 
    } 
    else 
    { 
     var onlydir=[]; 
     var onlyfiles=[]; 
     var d=(index)=> 
      { 
       if (index==files.length) 
        { 
         console.log("last index: "+ index); 

         var ar=[]; 
         ar.concat(onlydir,onlyfiles); 
         callback(null,ar); 
         return; 
        } 
       fs.stat(files[index],(err,status)=> 
        { 
         console.log("the needed file " +files[index]); 
        if (status.isDirectory()) 
         { 
         onlydir.push(files[index]); 
         } 
         else 
         { 
          onlyfiles.push(files[index]); 
         } 

         console.log("only Directory: "+onlydir.length); 
         console.log("index: "+ index); 
         d(index+1); 

        } 
       ) 

      } 
     d(0); 
    } 
}); 

}