2010年2月24日 星期三

讀取大型文字檔

以往在讀取文字檔時,會使用 File.ReadAllLines 方法,一次取得所有行。如下

static void Main(string[] args)
{
  string[] lines = File.ReadAllLines("TextFile1.txt");
  foreach (var line in lines)
    Console.WriteLine(line);
}

相當簡單。但這樣的方法,遇到大型文字檔,例如100MB時,就很麻煩了。原因在ReadAllLines 時就會一次將所有的資料讀到 lines 中,可能造成記憶體不足。

在 c# 2.0 時,介紹了 yield 的語法。在 c#3.0 時,介紹了 LINQ 語法。於是上述的問題就可以解了。如下

static void Main(string[] args)
{
  //string[] lines = File.ReadAllLines("TextFile1.txt"); // may need large memory
  var lines = ReadLines("TextFile1.txt");  //not consume large memory
  foreach (var line in lines)
    Console.WriteLine(line);
}

public static IEnumerable<string> ReadLines(string filePath)
{
  using (StreamReader reader = new StreamReader(filePath))
  {
    while (!reader.EndOfStream)
      yield return reader.ReadLine();
  }
}

上述的寫法很好。適合寫成常用的 framework! 因此,在 .net framework 4.0 中,已經將該段程式新增為 File.ReadLines

static void Main(string[] args)
{
  //string[] lines = File.ReadAllLines("TextFile1.txt"); // may need large memory
  var lines = File.ReadLines("TextFile1.txt"); // not need large memory, new in .net framework 4.0
  foreach (var line in lines)
    Console.WriteLine(line);
}

 

類似新增的方法,有

File.WriteAllLines, File.AppendAllLines, Directory.EnumerateDirectories, Directory.EnumerateFiles, Directory.EnumerateFileSystemEntries, DirectoryInfo.EnumerateDirectories, DirectoryInfo.EnumerateFiles, DirectoryInfo.EnumerateFileSystemInfos

沒有留言:

Share with Facebook