基本原理就是通过Stream的BeginRead来异步复制文件,同时刷新进度条的状态
1、通过StreamReader的Readline
通过StreamReader 读取
StreamReader sr = new StreamReader("E:\\abc.txt");
Console.WriteLine("Peek读取");
var i = 0;
while (sr.Peek() >= 0)
{
if (++i == 50000000-1)
{
Console.WriteLine(sr.ReadLine());
break;
}
continue;
}
sr.Close();
2、通过 FileStream.seek()来读取
Seek()方法的定义如下
public override long Seek (
long offset,
SeekOrigin origin
)
只要知道offset就可以了!
于是我们可以定义一个类,将每行开始的offset找出来,有了每行开始的offset,读取就自然不成问题了
Code
public class ReadByLine
{
public ReadByLine(string name)
{
PositionMap=new List<long>();
FileName = name;
Done = false;
}
public bool Done
{
get;
set;
}
/**//// <summary>
/// 当前流位置
/// </summary>
public long Position { get; set; }
/**//// <summary>
/// 文件的行数
/// </summary>
public long Lines { get; set; }
/**//// <summary>
/// 文件名(包含路径)
/// </summary>
public string FileName { get; set; }
/**//// <summary>
/// 行位置列表
/// </summary>
public List<long> PositionMap { get; set; }
private StreamReader sr;
private FileStream fs;
/**//// <summary>
/// 打开文件
/// </summary>
/// <returns></returns>
public bool Open()
{
try
{
//初始化各流
sr = new StreamReader(FileName);
InitMap();
return true;
}
catch (Exception e)
{
return false;
}
}
private void InitMap()
{
Lines = 1;
Position = 0;
//在地图中加入首条数据的位置信息
PositionMap.Add(Position);
//顺序建立文件地图
while (sr.Peek()>0)
{
var str = sr.ReadLine();
Position +=Encoding.UTF8.GetBytes(str).Length+ 2;
PositionMap.Add(Position);
Lines++;
}
Done = true;
sr.Close();
}
public string ReadLine(int line)
{
bool flag = true;
var str="";
while (flag)
{
if (!Done) continue;
fs = new FileStream(FileName, FileMode.Open);
fs.Seek(PositionMap[line], SeekOrigin.Begin);
var reader = new StreamReader(fs);
str = reader.ReadLine();
reader.Close();
fs.Close();
flag = false;
}
return str;
}
public bool Close()
{
try
{
//fs.Close();
sr.Close();
return true;
}
catch
{
return false;
}
}
}