C# 如何提高从文件流逐行读取字节的性能
我有一个大于10G的文件。 为了逐行读取这个文件,我编写了这个函数C# 如何提高从文件流逐行读取字节的性能,c#,.net,performance,file,C#,.net,Performance,File,我有一个大于10G的文件。 为了逐行读取这个文件,我编写了这个函数 static IEnumerable<string> fread(string fname, Encoding enc) using (var f = File.OpenRead(fname)) using (var reader = new StreamReader(f, enc)) while (!reader.EndOfStream) yield return reader.Rea
static IEnumerable<string> fread(string fname, Encoding enc)
using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f, enc))
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
static IEnumerable<byte[]> freadbytes(string fname) {
using (var f = File.OpenRead(fname)) {
var bufSz = 1024;
var buf = new byte[bufSz];
var read = 1;
var cr = (byte)13; // \r
var lf = (byte)10; // \n
var data = new List<byte>();
while (read > 0) {
read = f.Read(buf, 0, bufSz);
data.AddRange(read == bufSz ? buf : buf.slc(0, read));
var i = data.IndexOf(lf);
while (i >= 0) {
if (i > 0 && data[i - 1] == cr) yield return data.Take(i - 1).ToArray();
else yield return data.Take(i).ToArray();
data.RemoveRange(0, i + 1);
i = data.IndexOf(lf);
}
}
}
}
静态IEnumerable fread(字符串fname,编码enc)
使用(var f=File.OpenRead(fname))
使用(变量读取器=新的流读取器(f,enc))
而(!reader.EndOfStream)
产生返回reader.ReadLine();
}
这段代码运行得很好,但它返回的是一个行字符串,而不是行字节[]。
因此,为了为每行返回字节[],我编写了另一个函数
static IEnumerable<string> fread(string fname, Encoding enc)
using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f, enc))
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
static IEnumerable<byte[]> freadbytes(string fname) {
using (var f = File.OpenRead(fname)) {
var bufSz = 1024;
var buf = new byte[bufSz];
var read = 1;
var cr = (byte)13; // \r
var lf = (byte)10; // \n
var data = new List<byte>();
while (read > 0) {
read = f.Read(buf, 0, bufSz);
data.AddRange(read == bufSz ? buf : buf.slc(0, read));
var i = data.IndexOf(lf);
while (i >= 0) {
if (i > 0 && data[i - 1] == cr) yield return data.Take(i - 1).ToArray();
else yield return data.Take(i).ToArray();
data.RemoveRange(0, i + 1);
i = data.IndexOf(lf);
}
}
}
}
静态IEnumerable字节(字符串fname){
使用(var f=File.OpenRead(fname)){
var bufSz=1024;
var buf=新字节[bufSz];
var read=1;
var cr=(字节)13;//\r
变量lf=(字节)10;//\n
var data=新列表();
while(读取>0){
read=f.read(buf,0,bufSz);
data.AddRange(read==bufSz?buf:buf.slc(0,read));
var i=数据索引(lf);
而(i>=0){
如果(i>0&&data[i-1]==cr)产生返回数据.Take(i-1).ToArray();
否则产生返回数据.Take(i).ToArray();
数据删除范围(0,i+1);
i=数据索引f(lf);
}
}
}
}
第二个函数freadbytes()也可以正常工作,但问题是第二个函数占用的时间是第一个函数的10倍以上。
要使第二个函数更快,我可以做什么?虽然未经测试,但我相信这将大大加快速度:
static IEnumerable<byte[]> fread(string fname, Encoding enc)
{
using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f, enc))
while (!reader.EndOfStream)
yield return enc.GetBytes(reader.ReadLine());
}
静态IEnumerable fread(字符串fname,编码enc)
{
使用(var f=File.OpenRead(fname))
使用(变量读取器=新的流读取器(f,enc))
而(!reader.EndOfStream)
产生返回enc.GetBytes(reader.ReadLine());
}
也许这会有帮助:
static IEnumerable<string> fread(string fname, Encoding enc)
using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f, enc))
while (!reader.EndOfStream)
yield return enc.GetBytes(reader.ReadLine());
}
静态IEnumerable fread(字符串fname,编码enc)
使用(var f=File.OpenRead(fname))
使用(变量读取器=新的流读取器(f,enc))
而(!reader.EndOfStream)
产生返回enc.GetBytes(reader.ReadLine());
}
更新:最初错过了
enc
参数 这是文本文件还是二进制文件?如果是文本,为什么需要字节?如果它是二进制的,为什么要寻找换行符呢?如果你用的是行,二进制的速度不会太快。不是说你不能在二进制中加速,但是行的概念与文本有关,而不是字节。这是一个文本文件,但它包含一些韩文字符。要解析每一行,我应该使用给定的数据规范根据字节数拆分行。我曾尝试使用行字符串进行解析,但由于韩语字符,字节长度与字符串长度不匹配。似乎使用给定的数据规范,我应该将行的某些部分解码为ASCII,而一行的其他部分作为ANSI或韩语字符集。我不知道这是不是一个好办法。还有其他建议吗?@tk:老实说,听起来你需要在问题中提供更多的细节。告诉我们具体是什么。部分改变编码的格式可能会让人很痛苦,如果没有更多的信息,很难帮助你。快告诉我吧!而且我没有注意到enc
param!哇,我不知道这会这么简单。性能似乎比我的freadbytes()函数快3倍。考虑到编码是作为参数提供的,最好使用它。还有,你的退货类型现在不正确了。我错过了。我被这样一条信息弄得心烦意乱:“新答案已经发布了”:p