C# 如何从memorystream读取文本文件而不丢失字节

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) {

我正在写一些代码来学习新的c#异步设计模式。所以我想写一个小的windows窗体程序,计算文本文件的行数和字数,并显示阅读进度

为了避免磁盘交换,我将文件读入MemoryStream,然后构建一个StreamReader来逐行读取文本并计数

问题是我无法正确更新progressbar。 我读了一个文件,但总是有字节丢失,所以progressbar不能完全填充

需要一只手或一个想法来实现这一点。谢谢

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