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,每次可以读取出几百甚至上千行数据。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值