2012-10-01 185 views
-4

我有此代碼:文件在C#中搜索

string[] paths = GetFiles(dir).ToArray(); 

int numberOfFiles = paths.Length; 
int i = 0; 
while (i < numberOfFiles - 1) 
{ 
    scanfile(paths[i]); 
    i++; 
} 

而爲的GetFiles:

static IEnumerable<string> GetFiles(string path) { 
Queue<string> queue = new Queue<string>(); 
queue.Enqueue(path); 
while (queue.Count > 0) 
{ 
    path = queue.Dequeue(); 
    try 
    { 
     foreach (string subDir in Directory.GetDirectories(path)) 
     { 
      queue.Enqueue(subDir); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.Error.WriteLine(ex); 
    } 
    string[] files = null; 
    try 
    { 
     files = Directory.GetFiles(path); 
    } 
    catch (Exception ex) 
    { 
     Console.Error.WriteLine(ex); 
    } 
    if (files != null) 
    { 
     for (int i = 0; i < files.Length; i++) 
     { 
      yield return files[i]; 
     } 
    } 
} 
} 

public string scanfile(string path) 
    { 
     int offset = 0; 
     int length = 0; 
     byte[] buffer; 
     var variable1 = new StringBuilder(); 

     FileInfo fi = new FileInfo(path); 
     length = (int)fi.Length; 


      using (var mmf1 = MemoryMappedFile.CreateFromFile(path, 
       FileMode.OpenOrCreate, null, offset + length)) 
      { 
       // Create reader to MMF 
       using (var reader = mmf1.CreateViewAccessor(300, 
       4000, MemoryMappedFileAccess.Read)) 
       { 
        // Read from MMF 
        buffer = new byte[4000]; 
        reader.ReadArray<byte>(0, buffer, 0, 4000); 
       } 
      } 

     return variable1.ToString(); 

    } 

P.S:找我把它從堆棧溢出過的文件。

但是,如果我將它用於目錄中的許多文件時速度很慢,因爲它首先計算目錄中的文件。

你能幫我優化這些代碼嗎?

+15

這段代碼不會「非常慢」 - 它將是無限的,因爲你永遠不會改變'i'或'numerOfFiles'的值。這表明這不是你的真實代碼,這使得很難進一步診斷你的問題。 –

+1

另外,你似乎沒有顯示'scanfile'或'GetFiles'的功能,以及爲什麼你需要它在一個數組中? – Arran

+2

我會建議這個答案:http://stackoverflow.com/questions/724148/is-there-a-faster-way-to-scan-through-a-directory-recursively-in-net/724184#724184 –

回答

1

您應該使用foreach循環遍歷GetFiles的結果,而不是將其作爲數組提取,然後掃描單個文件。

+0

但如果我使用foreach循環,它有一個錯誤「訪問路徑被拒絕」 – Michael

+0

我已經使用了foreach方法很多次。它運作良好,速度非常快! –

+0

您正在調用不需要的ToArray方法。此外,迭代器有一些優化,這將使其稍快。 「訪問路徑被拒絕」錯誤與foreach循環無關。請確保您有權訪問您試圖訪問的文件 –

2

好吧,讓我們看看我們是否可以簡化這一點。讓我們用這個代碼把所有的文件:

// Get list of files in the specific directory. 
// ... Please change the first argument. 
string[] files = Directory.GetFiles("{root path}", 
    "*.*", 
    SearchOption.AllDirectories); 

注意AllDirectories記錄爲這樣:

包括當前目錄及其在搜索操作中所有子目錄。此選項包括重新分析點,例如搜索中的裝入驅動器和符號鏈接。

現在就讓我們用一個簡單的循環foreach通過他們來獲得:

foreach (var file in files) 
{ 
    // ... do something 
} 

是否有一個原因,這是行不通的?

+0

它不會出現錯誤:「訪問路徑被拒絕」?! – Michael

+0

首先,它不是遞歸的,第二件事是訪問被拒絕的錯誤是文件系統問題,而不是你的代碼。您無法使用代碼解決它。您必須更改文件系統權限或使用適當的用戶權限運行代碼,以便它可以訪問所有文件。 –

+0

好的。那麼,這是因爲我的電腦有錯誤嗎?如果我在另一臺電腦上運行它,它會起作用嗎? – Michael

1

只要看看Directory.EnumerateFiles。他們也是如何迭代所有* .txt文件並獲取包含Microsoft的所有行的示例。

該示例還通過簡單地跳過此文件來照顧未經授權的訪問異常。