C#利用FileStream循环读取大文件

话不多说,直接上代码:

        /// <summary>
        /// FileStream循环读取大文件
        /// </summary>
        /// <param name="path">要读取的大文件地址</param>
        /// <param name="LastReadPosition">上一次读取结束时的流的位置 => fs.Position</param>
        /// <returns>本次读取结束时,流所在的位置(fs.Position或fs.Length)</returns>
        public static long DoParse_FileStream(string path, long LastReadPosition)
        {
            int bufferSize = 1024 * 1024;                                          // 缓冲区大小,一次最多读取该数目的字节。
            byte[] buffer = new byte[bufferSize];                                  // 缓冲区

            Encoding encode = Encoding.UTF8;                                        // 文本所用的编码

            string dataStr = string.Empty;                                          // 存储每次读取出的字符串
            List<string> dataList = new List<string>();                            // 用换行符分隔后的每行数据

            int len = 0;                                                            // 每次读取到缓冲区的字节数
            int index = 1;                                                          // 当前读取到多少行

            string separator = "\n";                                                // 每行之间的分隔符
            string halfLine = string.Empty;                                        // 每次分隔时出现的半行字符串

            try
            {
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                    fs.Seek(LastReadPosition, SeekOrigin.Begin);                    // 设置文件流的读取位置

                    while ((len = fs.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        dataStr = encode.GetString(buffer);                        // 将读取出的字节数组按编码转换为字符串

                        dataList = dataStr.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).ToList();

                        for (int i = 0; i < dataList.Count; i++)
                        {
                            if (i == 0)
                            {
                                dataList[i] = halfLine + dataList[i];              // 将上次读取最后的半行和本次读取的第一行合并,凑成完整的一行。
                            }

                            if (i == dataList.Count - 1)
                            {
                                if (Regex.IsMatch(dataStr, separator + @"\s*$"))
                                {
                                    halfLine = string.Empty;                        // 当读取的内容为完整的行,设置halfLine为空值。
                                }
                                else
                                {
                                    halfLine = dataList[i];                        // 当读取的内容不完整时,最后一项会是半行数据。
                                    continue;
                                }
                            }

                            #region 在这里循环遍历每一行数据

                            Console.WriteLine(index + ": " + dataList[i]);          // 这就是完整的每行数据
                            index++;

                            #endregion
                        }
                        buffer = new byte[bufferSize];                              // 每次fs读取前都需要先将buffer置为空,因为fs会将读取的内容“替换”到buffer的指定位置,当读取到最后一次时会出现冗余数据。
                    }

                    LastReadPosition = fs.Position;                                // 设置本次读取到的位置
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return LastReadPosition;
        }

使用说明:

1、使用时,直接在“#region 在这里循环遍历每一行数据”中编辑每一行即可。

2、每次读取出的buffer内容,应该是多行数据。以上代码中设置的buffer.Length为1024*1024,也即1M,每次可以读取出几百甚至上千行数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。