2011-08-01 23 views
35

ターゲットがディスクとラムで制限されているため、リストを使用してファイルサイズを制限しています。 これは私が今やっていることですが、より効率的な方法がありますか?リストをファイルに読み込む最良の方法<string>

readonly List<string> LogList = new List<string>(); 
... 
var logFile = File.ReadAllLines(LOG_PATH); 
foreach (var s in logFile) LogList.Add(s); 
+0

'LogList'に' readonly'とマークしたときにエントリを追加するのは難しくありませんか? – Tim

+4

これは、読み取り専用リストではなく参照を再割り当てできないことを意味します。 – Deleted

+0

あなたのタイトルに "C#"を入れてはいけません。質問の内容について言えば、それはタグのためです。 –

答えて

75
var logFile = File.ReadAllLines(LOG_PATH); 
var logList = new List<string>(logFile); 

が配列である、あなたはList<T>コンストラクタに渡すことができます。これにより、配列を反復処理するとき、または他のIOクラスを使用するときの不要なオーバーヘッドがなくなります。

Actual constructor implementation

public List(IEnumerable<T> collection) 
{ 
     ... 
     ICollection<T> c = collection as ICollection<T>; 
     if(c != null) { 
      int count = c.Count; 
      if (count == 0) 
      { 
       _items = _emptyArray; 
      } 
      else { 
       _items = new T[count]; 
       c.CopyTo(_items, 0); 
       _size = count; 
      } 
     } 
     ... 
} 
+0

ありがとうございます。私はこれを行う正しい方法がなければならないと考えました。 – jacknad

5

可能であれば保存しないでください。記憶が拘束されている場合は、それを読んでください。

using (var reader = new StreamReader("file.txt")) 
{ 
    var line = reader.ReadLine(); 
    // process line here 
} 

これは、あなたがLINQを使用したい場合は、読み込んだ行あたりの文字列を生成する方法でラップすることができます:あなたは、StreamReaderを使用することができます。 logFile以来

4

[編集]

ログファイルの先頭をトリミングするためにこれをやっている場合、あなたはこのような何かを行うことによって、ファイル全体を読み込む避けることができます。

以来
// count the number of lines in the file 
int count = 0; 
using (var sr = new StreamReader("file.txt")) 
{ 
    while (sr.ReadLine() != null) 
     count++; 
} 

// skip first (LOG_MAX - count) lines 
count = LOG_MAX - count; 
using (var sr = new StreamReader("file.txt")) 
using (var sw = new StreamWriter("output.txt")) 
{ 
    // skip several lines 
    while (count > 0 && sr.ReadLine() != null) 
     count--; 

    // continue copying 
    string line = ""; 
    while (line = sr.ReadLine() != null) 
     sw.WriteLine(line); 
} 

まず第一に、はファイル全体を文字列配列(string[])にロードし、リストへのコピーは冗長です。

第2に、フードの下でダイナミックアレイを使用してListが実装されていることを理解する必要があります。つまり、ファイル全体を格納できるようになるまで、CLRは複数の配列を割り当ててコピーする必要があります。このファイルはすでにディスク上にあるので、メモリのトランザクション速度とディスクデータの直接処理、またはそれを小さな単位で処理することが考えられます。

  1. あなたは、少なくとも配列に残すようにしようと、メモリに完全にそれをロードする必要がある場合:

    string[] lines = File.ReadAllLines("file.txt"); 
    
  2. それは本当にListにする必要がある場合は、負荷線一つずつ:

    List<string> lines = new List<string>(); 
    using (var sr = new StreamReader("file.txt")) 
    { 
         while (sr.Peek() >= 0) 
          lines.Add(sr.ReadLine()); 
    } 
    

    注:List<T>は、容量パラメータを受け取るコンストラクタを持っています。

    List<string> lines = new List<string>(NUMBER_OF_LINES); 
    
  3. はさらに良いことに、「オンザフライ」のメモリとそれを処理中に、ファイル全体を保管することは避けてください:あなたは、事前に行数がわかっている場合は、事前に配列を事前に割り当てることにより、複数の配分を防ぐことができます

    using (var sr = new StreamReader("file.txt")) 
    { 
         string line; 
         while (line = sr.ReadLine() != null) 
         { 
          // process the file line by line 
         } 
    } 
    
12

なぜ代わりに発電機を使用していませんか?もちろん

var logFile = ReadLogLines(LOG_PATH); 
foreach(var s in logFile) { 
    // Do whatever you need 
} 

あなたはList<string>を持っている必要があるならば、あなたはメモリにファイル全体の内容を維持する必要があります、:あなたは、リストを使用するように

private IEnumerable<string> ReadLogLines(string logPath) { 
    using(StreamReader reader = File.OpenText(logPath)) { 
     string line = ""; 
     while((line = reader.ReadLine()) != null) { 
      yield return line; 
     } 
    } 
} 

は、その後、あなたはそれを使用することができます。その周りには本当に方法はありません。

1
List<string> lines = new List<string>(); 
using (var sr = new StreamReader("file.txt")) 
{ 
     while (sr.Peek() >= 0) 
      lines.Add(sr.ReadLine()); 
} 

これはGrooの答えです。

29

エヴァンMulawskiの答えに少し更新が作るために、それより短く

List<string> allLinesText = File.ReadAllLines(fileName).ToList()

+0

あなたはevanBHOPSを意味しましたか? – napi15

+0

これを使用します。 +1! –

2
//this is only good in .NET 4 
//read your file: 
List<string> ReadFile = File.ReadAllLines(@"C:\TEMP\FILE.TXT").ToList(); 

//manipulate data here 
foreach(string line in ReadFile) 
{ 
    //do something here 
} 

//write back to your file: 
File.WriteAllLines(@"C:\TEMP\FILE2.TXT", ReadFile); 
+1

ReadFileは大文字で始めるべきではありません – Chrotenise

0
string inLine = reader.ReadToEnd(); 
myList = inLine.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList(); 

私も同様Environment.NewLine.toCharArrayを使用しますが、上で動作しないことが判明\ r \ nで終わったいくつかのファイル。どちらかを試してみてください

+0

ようこそ!コードのみの回答はここでは避けてください。これがどのようにして最良の答えになるかについての説明を追加できますか? –

関連する問題