现在我有一堆txt文件,需要通过程序读取记事本的每一行数据,记事本的数据量比较大的时候,程序每秒钟处理的行数也就30左右,那样的话,一个文件有几十万行数据就相当耗时间了。不知道有没有什么更快的速度进行读取记事本的每一行数据呢。
我原来的是逐行读取while ((currentLine = txtReader.ReadLine()) != null) {},这个对于小文件到无所谓,但是大文件就感觉相当慢了。
建议直接读到数据库的表,然后对标进行相关操作。
弄两个SSD硬盘,做成RAID0。
文件多也好办,多买几台服务器并行处理好了。
那首先我们得解决有十万数据的单文件速度吧,假设我现在只有一个文件,里面有十万行数据,如果靠逐行读取的话,这个跟ssd没有关系吧,这个逐行读取的方式就有问题。不知道有没有高效的方式
@说实话的秀才: 没有...必要.
当然如果你觉得这个有市场的话,你可以去研究。
纯粹从市场需求角度看,几乎没有意义。
1、没有人会在TXT里面存放一大堆数据。
2、即使有,也不会经常需要导入导出的。
3、一次性的工作,不管有多慢,成本都远远小于你去找快的解决方案的成本。
4、当然,你闲得发慌的话,可以花个一年半载的,研究下...,也说不定半个月一个月就研究出来。
@爱编程的大叔:
这个独立出来确实没有意义,一般情况下处理记事本都是数据量比较小的,对于大数据量的情况也就大点的项目才会用到。我是一个小工具中用到导入记事本到数据库的,因为逐行比较慢,而采用SQLite的数据库管理工具导入就比较快,所以想看看大家有没有对记事本读取的高效方法,实在没有,我就只有每次都得使用SQLite管理工具导入数据。
@说实话的秀才: 读是一个操作(消耗磁盘),最慢的。
读到内存后,有个处理工作(这个应该是比较快的),把这个扔给异步线程处理。
这样所有的时间就只是从磁盘读取的时间(几乎等于)。
然后要再优化,就只能用SSD+RAID0这样了。
@爱编程的大叔:
这个读取不就是一次性读进入内存的吗,而且十万数据的记事本也就几M,所以读不是问题,问题我感觉在于这个while循
@说实话的秀才: 这是一行行读,一行行处理。
不知道你们高中有没有读过华罗庚的统筹学的那一课。
生活中经常需要沏茶。如果当时的情况是:没有开水,开水壶、茶壶、茶杯都要洗,还需要准备茶叶,应该怎么安排?
烧开水5分钟,洗茶壶1分钟,洗茶杯2分钟,准备茶叶1分钟,请问一共需要多少分钟。
办法甲:先做好准备工作,洗开水壶、茶壶、茶杯,拿茶叶。一切就绪后,灌水,烧水,等水开了泡茶喝。
办法乙:洗净开水壶后,灌水,烧水。等水开了之后,洗茶壶、茶杯,拿茶叶,泡茶喝。
办法丙:洗净开水壶后,灌水,烧水。利用等待水开的时候,洗茶壶、茶杯,拿茶叶,等水开了泡茶喝。
哪种办法节省时间?显然是办法丙,因为前两种办法都“窝工”了。
你在while里面的所有代码都扔给别的线程做,就是我说的方法了。
不过你要是不懂线程,那我就只能建议你去看书了。
string File_path = @"d:\Test_File.txt";
StreamReader sr = File.OpenText(File_path);
textBox2.Text = sr.ReadToEnd();
我觉得用ReadToEnd()会快一点
注意哦,大文件,小心噎到了...
当然,具体分析的话,可能要做好多测试才看得出来。
一是要看平均的文件大小,二是要看读入后处理的时间与读取的时间比例。
有可能你的方法快也说不定。
不过说实话,研究这事纯粹是浪费时间。
正常情况下就应该是每行读+异步处理。
一、可以避免界面长时间吊死
二、可以用多线程将后期处理时间基本大部份节省下来。
@爱编程的大叔:
超大文件读写用MMF, 内存映射文件呀!
当然,文件没1G以上当我没说。
@XiaoFaye: 学习了,谢谢!
内存映射读大文件, .net 4.0下已经很方便了, https://msdn.microsoft.com/zh-cn/library/vstudio/dd997372.aspx
如果项目是之前的, 那你就只能通过系统api了。
一些文本编辑器就是这么干的, 如果你用的是ssd, 读取速度更快。
sqlbulkCopy 有一种本地文件直接写入数据库的方法
demo:
create database DB_Temp
go
use DB_Temp
go
create table test
(
id int ,
name nvarchar(255)
)
go
bulk insert DB_Temp.dbo.test from 'd:\1.txt'
with
(
fieldterminator=',',
rowterminator='\n'
)
go
SELECT * FROM dbo.test