C# 如何最好地将文件读入列表<;字符串>;

C# 如何最好地将文件读入列表<;字符串>;,c#,compact-framework,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); readonly List LogList=new List(); ... var

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

readonly List<string> LogList = new List<string>();
...
var logFile = File.ReadAllLines(LOG_PATH);
foreach (var s in logFile) LogList.Add(s);
readonly List LogList=new List();
...
var logFile=File.ReadAllLines(日志路径);
foreach(日志文件中的var s)LogList.Add(s);

如果可能,不要存储它。如果你的记忆有限,就通读一遍。您可以使用StreamReader:

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

如果要使用LINQ,可以将其包装在一个方法中,该方法在每行读取时生成字符串。

[Edit]

var logFile = File.ReadAllLines(LOG_PATH);
var logList = new List<string>(logFile);
如果您这样做是为了修剪日志文件的开头,可以通过执行以下操作来避免加载整个文件:

// 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[]
)中,因此复制到列表是多余的

其次,您必须了解
列表
是使用引擎盖下的动态数组实现的。这意味着CLR将需要分配和复制多个数组,直到它能够容纳整个文件。由于文件已经在磁盘上,您可能会考虑内存的速度和直接处理磁盘数据,或者以较小的块处理它。
  • 如果需要将其完全加载到内存中,请至少尝试将其保留在数组中:

     string[] lines = File.ReadAllLines("file.txt");
    
  • 如果它确实需要成为一个
    列表
    ,请逐个加载行:

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

  • 为什么不改用发电机呢

    private IEnumerable<string> ReadLogLines(string logPath) {
        using(StreamReader reader = File.OpenText(logPath)) {
            string line = "";
            while((line = reader.ReadLine()) != null) {
                yield return line;
            }
        }
    }
    
    当然,如果需要一个
    列表
    ,则需要将整个文件内容保存在内存中。真的没有办法解决这个问题。

    列表行=新列表();
    List<string> lines = new List<string>();
     using (var sr = new StreamReader("file.txt"))
     {
          while (sr.Peek() >= 0)
              lines.Add(sr.ReadLine());
     }
    
    使用(var sr=newstreamreader(“file.txt”)) { 而(sr.Peek()>=0) 添加(sr.ReadLine()); }
    我建议。。。Groo的答案。

    对Evan Mulawski的答案进行了一些更新,使其更简短

    List allLinesText=File.ReadAllLines(fileName).ToList()

    //这仅适用于.NET 4
    //阅读您的文件:
    List ReadFile=File.ReadAllLines(@“C:\TEMP\File.TXT”).ToList();
    //在这里操作数据
    foreach(ReadFile中的字符串行)
    {
    //在这里做点什么
    }
    //写回您的文件:
    writeAllines(@“C:\TEMP\FILE2.TXT”,ReadFile);
    
    我还使用了Environment.NewLine.toCharArray,但发现这在以\r\n结尾的几个文件上不起作用。试试其中任何一种,我希望它对你有用

    string inLine = reader.ReadToEnd();
    myList = inLine.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
    
    这个答案忽略了最初的一点,那就是他们得到了一个OutOfMemory错误。如果您继续使用上述版本,那么如果您的系统没有合适的连续可用ram来加载文件,您肯定会点击它


    您只需将其分解为多个部分,并以列表或字符串[]的形式存储

    你可以这样简单地阅读

    List<string> lines = System.IO.File.ReadLines(completePath).ToList();
    
    List lines=System.IO.File.ReadLines(completePath.ToList();
    
    当您将其标记为
    只读时,向
    日志列表
    添加条目不是很难吗?这意味着您不能重新分配引用,而不是将其设置为只读列表。@JackN:您如何使用列表限制文件大小,您能解释一下吗?@Tim:向列表添加条目是通过
    添加
    方法完成的。与任何其他对象一样,列表只分配给一个字段一次,但这并不妨碍您修改其自身的属性和字段。@Tim-对于引用类型,这只意味着您不能更改引用本身。这并不意味着你不能修改引用对象的成员。非常感谢。我认为必须有一种正确的方法来实现这一点。实际上,由于必须在数组上创建枚举器,这会增加开销。但不会有太多开销。欢迎使用堆栈溢出!这里不鼓励只使用代码的答案。你能解释一下这是如何最好地回答这个问题的吗?ReadFile不应该以大写字母开头。应该注意的是,
    ReadLines
    就是你在这里所做的
    foreach(File.ReadLines(@“d:\data\scents.txt”)中的字符串行)
    var logFile = ReadLogLines(LOG_PATH);
    foreach(var s in logFile) {
        // Do whatever you need
    }
    
    List<string> lines = new List<string>();
     using (var sr = new StreamReader("file.txt"))
     {
          while (sr.Peek() >= 0)
              lines.Add(sr.ReadLine());
     }
    
    //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);
    
    string inLine = reader.ReadToEnd();
    myList = inLine.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
    
    string inLine = reader.ReadToEnd();
    myList = inLine.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
    
    List<string> lines = System.IO.File.ReadLines(completePath).ToList();