C# 如何从memorystream读取文本文件而不丢失字节
我正在写一些代码来学习新的c#异步设计模式。所以我想写一个小的windows窗体程序,计算文本文件的行数和字数,并显示阅读进度 为了避免磁盘交换,我将文件读入MemoryStream,然后构建一个StreamReader来逐行读取文本并计数 问题是我无法正确更新progressbar。 我读了一个文件,但总是有字节丢失,所以progressbar不能完全填充 需要一只手或一个想法来实现这一点。谢谢C# 如何从memorystream读取文本文件而不丢失字节,c#,async-await,c#-5.0,C#,Async Await,C# 5.0,我正在写一些代码来学习新的c#异步设计模式。所以我想写一个小的windows窗体程序,计算文本文件的行数和字数,并显示阅读进度 为了避免磁盘交换,我将文件读入MemoryStream,然后构建一个StreamReader来逐行读取文本并计数 问题是我无法正确更新progressbar。 我读了一个文件,但总是有字节丢失,所以progressbar不能完全填充 需要一只手或一个想法来实现这一点。谢谢 public async Task Processfile(string fname) {
public async Task Processfile(string fname)
{
MemoryStream m;
fname.File2MemoryStream(out m); // custom extension which read file into
// MemoryStream
int flen = (int)m.Length; // store File length
string line = string.Empty; // used later to read lines from streamreader
int linelen = 0; // store current line bytes
int readed = 0; // total bytes read
progressBar1.Minimum = 0; // progressbar bound to winforms ui
progressBar1.Maximum = flen;
using (StreamReader sr = new StreamReader(m)) // build streamreader from ms
{
while ( ! sr.EndOfStream ) // tried ( line = await sr.ReadLineAsync() ) != null
{
line = await sr.ReadLineAsync();
await Task.Run(() =>
{
linelen = Encoding.UTF8.GetBytes(line).Length; // get & update
readed += linelen; // bytes read
// custom function
Report(new Tuple<int, int>(flen, readed)); // implements Iprogress
// to feed progress bar
});
}
}
m.Close(); // releases MemoryStream
m = null;
}
公共异步任务进程文件(字符串fname)
{
记忆流m;
fname.File2MemoryStream(out m);//将文件读入的自定义扩展名
//记忆流
int flen=(int)m.Length;//存储文件长度
string line=string.Empty;//稍后用于从streamreader读取行
int linelen=0;//存储当前行字节
int readed=0;//读取的字节总数
progressBar1.Minimum=0;//绑定到winforms ui的progressbar
progressBar1.最大值=flen;
使用(StreamReader sr=new StreamReader(m))//从ms构建StreamReader
{
while(!sr.EndOfStream)//已尝试(line=wait sr.ReadLineAsync())!=null
{
line=wait sr.ReadLineAsync();
等待任务。运行(()=>
{
linelen=Encoding.UTF8.GetBytes(line).Length;//获取和更新
readed+=linelen;//读取字节数
//自定义函数
报表(新元组(flen,readed));//实现Iprogress
//输入进度条
});
}
}
m、 Close();//释放内存流
m=零;
}
分配给flen的总长度包括每行的回车。函数的作用是:返回不包含回车符的字符串。我的猜测是,进度条中丢失的字节数与正在读取的文件中的回车数成正比。分配给flen的总长度包括每行的回车数。函数的作用是:返回不包含回车符的字符串。我的猜测是,进度条中丢失的字节数与正在读取的文件中的回车数成正比。使用MemoryStream可能没有任何好处;FileStream和StreamReader都被智能缓冲。@SLaks是的,这些类被缓冲,但我将整个归档文件读入MemoryStream以获得性能。我认为分块读取文件的速度较慢,因为需要更多的I/O。@ppk-除非您在流上进行任何查找,否则将整个文件读取到MemoryStream是愚蠢的,如果您只想按顺序处理文件。操作系统已经在智能地将文件读入内存。或者换一种说法,不要试图在没有测量的情况下进行优化。目前,您似乎已经猜到,将其放入MemoryStream将(以某种方式)产生更好的性能。感谢所有人的帮助。使用MemoryStream可能没有任何好处;FileStream和StreamReader都被智能缓冲。@SLaks是的,这些类被缓冲,但我将整个归档文件读入MemoryStream以获得性能。我认为分块读取文件的速度较慢,因为需要更多的I/O。@ppk-除非您在流上进行任何查找,否则将整个文件读取到MemoryStream是愚蠢的,如果您只想按顺序处理文件。操作系统已经在智能地将文件读入内存。或者换一种说法,不要试图在没有测量的情况下进行优化。目前,您似乎已经猜到,将其放入MemoryStream将(以某种方式)产生更好的性能。感谢所有人的帮助。Encoding.Getbytes文档没有提到任何不包括回车的内容。但是我要测试它。@ppk-不是编码。GetBytes
删除回车符-是调用一个永远不会返回回车符编码的函数(ReadLineAsync
)。GetBytes文档没有提到不包含回车符的任何内容。不过,我要测试它。@ppk-删除回车符的不是编码.GetBytes
,而是调用一个永远不会返回回车符的函数(readlinesync
)