如何最好地将文件读入List <string> </string>

时间:2011-08-01 20:59:28

标签: c# compact-framework

我使用列表来限制文件大小,因为目标在磁盘和RAM中是有限的。 这就是我现在正在做的,但有更有效的方法吗?

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

10 个答案:

答案 0 :(得分:96)

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

由于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;
            }
        }   
        ...
} 

答案 1 :(得分:46)

对Evan Mulawski的一点回应是为了缩短

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

答案 2 :(得分:13)

为什么不使用发电机?

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

然后您可以像使用列表一样使用它:

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

当然,如果您需要List<string>,那么您需要将整个文件内容保留在内存中。真的没办法解决这个问题。

答案 3 :(得分:5)

<强> [编辑]

如果您这样做是为了修剪日志文件的开头,您可以通过执行以下操作来避免加载整个文件:

// 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);
}

首先,由于File.ReadAllLines将整个文件加载到字符串数组(string[]),因此复制到列表是多余的。

其次,您必须了解使用动态数组实现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
          }
     }
    

答案 4 :(得分:4)

如果可能,请勿存放。如果您受到内存限制,请仔细阅读。您可以使用StreamReader:

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

这可以包含在一个方法中,如果你想使用LINQ,它会产生每行读取的字符串。

答案 5 :(得分: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);

答案 6 :(得分:1)

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

我会建议...... Groo的答案。

答案 7 :(得分:1)

您可以通过这种方式简单阅读。

List<string> lines = System.IO.File.ReadLines(completePath).ToList();

答案 8 :(得分:0)

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

我也使用了Environment.NewLine.toCharArray,但发现它并没有对以\ r \ n结尾的几个文件起作用。尝试任何一个,我希望它适合你。

答案 9 :(得分:0)

string inLine = reader.ReadToEnd(); myList = inLine.Split(新字符串[] {“ \ r \ n”},StringSplitOptions.None).ToList();

这个答案错过了原来的观点,那就是他们遇到了OutOfMemory错误。如果继续使用上述版本,请确保在系统没有适当的连续可用RAM加载文件的情况下将其选中。

您只需将其分成几部分,并以两种方式存储为List或String []。