计算非常大文件中的行数会导致 System OutofMemory 异常 [重复]

Posted

技术标签:

【中文标题】计算非常大文件中的行数会导致 System OutofMemory 异常 [重复]【英文标题】:Counting the # of lines in a very large file gives System OutofMemory Exception [duplicate] 【发布时间】:2017-07-19 15:26:38 【问题描述】:
static void Main(string[] args) 


    string TheDataFile = "";
    string ErrorMsg = "";
    string lngTransDate = "";
    ProcessDataFile  ProcessTheDataFile = new ProcessDataFile();

    string TheFile = "S:\\MIS\\Provider NPI file\\Processed\\npidata_20050523-20161009.csv";
    string[] lines = File.ReadAllLines(TheFile, Encoding.UTF8);//Read all lines to an array 
    Console.WriteLine(lines.Length.ToString());
    Console.ReadLine();

这会引发错误,因为文件非常大(有 600 万行)。有没有办法处理大文件并计算行数?

【问题讨论】:

逐行阅读。看到这个example。 如果您只想获取行数,请将其流式传输并逐行循环以获取计数。这样你就不会记住整个事情。 Maybe this post can help 顺便说一句,您不需要 lines.Length 上的 .ToString()... Console.WriteLine 可以很好地处理整数。 【参考方案1】:

使用StreamReader

string TheFile = "S:\\MIS\\Provider NPI file\\Processed\\npidata_20050523-20161009.csv";
int count = 0;
using (System.IO.StreamReader sr = new System.IO.StreamReader(TheFile))

    while (sr.ReadLine() != null)
        count++;

【讨论】:

在一个 1.6GB 的数据文件上,这种方法使用的内存只有我的一半。【参考方案2】:

您需要对文件进行惰性求值,使其不会完全加载到内存中。

辅助方法

public static class ToolsEx

    public static IEnumerable<string> ReadAsLines(this string filename)
    
        using (var streamReader = new StreamReader(filename))
            while (!streamReader.EndOfStream)
                yield return streamReader.ReadLine();
    

用法

var lineCount = "yourfile.txt".ReadAsLines().Count();

【讨论】:

我个人将方法称为EnumerateLines,因此它遵循Directory.GetFiles()/Directory.EnumerateFiles() 模式。也不要让它成为string 的扩展方法,做"yourfile.txt".ReadAsLines() 对我来说看起来很奇怪。 这是你的意见......我不同意它:) 目的是读取文件。非程序员也更容易理解ReadEnumerate 的区别。 (在我看来) 我同意@ScottChamberlain 并非所有字符串都是文件。这就是奇怪的部分。 如果它能让你感觉更好,那么就这样使用它...var lineCount = ToolsEx.ReadAsLines(filename:"yourfile.txt").Count() 我和@ScottChamberlain 一起讨论string 扩展方法。而且根本不需要这样的辅助方法,因为它复制了File.ReadLines【参考方案3】:

According to this already accepted answer,应该这样做。

using System;
using System.IO;

namespace CountLinesInFiles_45194927

    class Program
    
        static void Main(string[] args)
        
            int counter = 0;
            foreach (var line in File.ReadLines("c:\\Path\\To\\File.whatever"))
            
                counter++;
            
            Console.WriteLine(counter);
            Console.ReadLine();
        
    

【讨论】:

@ScottChamberlain,使用 1.6GB 的数据文件,VSHost 进程,使用 OP 的方式,使用了超过 5GB 的内存。我的方式没有超过 14mb。更何况 OP 的方式也需要更长的时间来处理。

以上是关于计算非常大文件中的行数会导致 System OutofMemory 异常 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

PowerShell:如何计算 csv 文件中的行数?

读取大文本文件VB6中的行数

Node.js:计算文件中的行数

转载python计算文件的行数和读取某一行内容的实现方法

(Python)尽可能快地计算一个巨大(> 10GB)文件中的行数[重复]

如何有效地计算数据帧的行数? [复制]