ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 读取非常大的文本文件,我应该合并异步吗?

2019-05-29 14:54:31  阅读:209  来源: 互联网

标签:c asynchronous streamreader


我一直面临着制作一种方法的挑战,该方法将非常大的文本文件读入程序,这些文件的范围可以从2gb到100gb.

到目前为止,这个想法一直是读取方法中的几千行文本.

目前,使用流阅读器设置程序,逐行读取文件并处理在该行上找到的必要数据区域.

using (StreamReader reader = new StreamReader("FileName"))
{
    string nextline = reader.ReadLine();
    string textline = null;

    while (nextline != null)
    {
        textline = nextline;
        Row rw = new Row();
        var property = from matchID in xmldata
                       from matching in matchID.MyProperty
                       where matchID.ID == textline.Substring(0, 3).TrimEnd()
                       select matching;

        string IDD = textline.Substring(0, 3).TrimEnd();

        foreach (var field in property)
        {
            Field fl = new Field();

            fl.Name = field.name;
            fl.Data = textline.Substring(field.startByte - 1, field.length).TrimEnd();
            fl.Order = order;
            fl.Show = true;

            order++;

            rw.ID = IDD;
            rw.AddField(fl);
        }
        rec.Rows.Add(rw);
        nextline = reader.ReadLine();

        if ((nextline == null) || (NewPack == nextline.Substring(0, 3).TrimEnd()))
        {
            d.ID = IDs.ToString();
            d.Records.Add(rec);
            IDs++;
            DataList.Add(d.ID, d);
            rec = new Record();

            d = new Data();
        }
    }
}

该程序继续进行并填充一个类. (刚决定不发布其余的)

我知道一旦程序显示一个非常大的文件,就会发生内存异常错误.

所以这是我目前的问题,到目前为止我一直在谷歌搜索几种方法,很多人只是回答使用流阅读器和reader.readtoend,我知道readtoend不会为我工作,因为我会得到那些内存错误.

最后,我一直在研究异步作为一种创建方法的方法,该方法将在处理下一行数量之前读取一定数量的行并等待调用.

这让我想到了我的问题,我正在努力理解异步,我似乎无法找到任何可以帮助我学习的材料,并希望有人在这里可以帮助我了解异步的方法.

当然,如果有人知道更好的方法来解决这个问题,我很满意.

编辑添加了剩余的代码以结束任何混淆.

解决方法:

你的问题不是同步v的异步,而是你在读取整个文件并在对数据执行某些操作之前将文件的一部分存储在内存中.

如果您正在读取每一行,处理它并将结果写入另一个文件/数据库,那么StreamReader将允许您处理多GB(或TB)文件.

如果您在完成阅读之前存储了部分文件,那么只会出现问题,那么您可能会遇到内存问题(但是您会惊讶地发现,在内存不足之前,Lists& Dictionaries会有多大)

您需要做的是尽快保存已处理的数据,而不是将其保留在内存中(或尽可能保留在内存中).

对于大型文件,您可能需要将工作集(处理数据)保存在数据库中 – 可能像SqlExpress或SqlLite那样(但同样,它取决于工作集的大小).

希望这有帮助,不要犹豫,在评论中提出进一步的问题,或编辑你的原始问题,如果我能以任何方式提供帮助,我会更新这个答案.

更新 – 分页/分块

您需要以一页的块读取文本文件,并允许用户滚动文件中的“页面”.当用户滚动时,您将阅读并在下一页中显示它们.

现在,您可以做一些事情来帮助自己,始终在内存中保留大约10页,这样,如果用户非常快速地向上/向下翻页几页,您的应用就可以做出响应.在应用程序空闲时间(应用程序空闲事件)中,您可以在接下来的几页中读取,再次丢弃当前页面之前或之后超过五页的页面.

向后分页是一个问题,因为您不知道每行在文件中的开始或结束位置,因此您不知道每个页面的开始或结束位置.因此,对于向后翻页,当您通读文件时,请在每个页面的开头(Stream.Pos)保留一个偏移列表,然后您可以快速搜索到给定位置并从那里读取页面.

如果您需要允许用户搜索文件,那么您几乎可以逐行读取文件(记住页面偏移,然后查找文本),然后当您找到某些内容时,请阅读并使用那个页面.

您可以通过将文件预处理到数据库来加速一切,有一些网格控件可以处理动态数据集(它们将为您进行分页),并且您可以获得内置搜索/过滤器的好处.

因此,从某个角度来看,这是异步读取文件,但这是从用户的角度来看.但从技术角度来看,当我们谈论在编程时做异步时,我们往往会有别的意思.

标签:c,asynchronous,streamreader
来源: https://codeday.me/bug/20190529/1178746.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有