并行读取一个非常大的文件 C#
Read a very large files in parallel C#
我有 20 多个文件,每个文件包含近 100 万行(5 GB),我需要加快读取过程,所以我尝试并行读取这些文件,但需要更长的时间时间比顺序阅读它们。有没有办法并行读取非常大的文件?
Parallel.ForEach(sourceFilesList, filePath =>
{
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
StreamReader str = new StreamReader(filePath);
while (!str.EndOfStream)
{
var temporaryObj = new object();
string line = str.ReadLine();
// process line here
}
}
});
它的IO操作,建议像下面这样使用Async/Await(主要使用ReadAsync
函数,有助于异步读取),Async/Await使用你们 Machine Physical Core
的效率很高。
public void ReadFiles()
{
List<string> paths = new List<string>(){"path1", "path2", "path3"};
foreach(string path in Paths)
{
await ProcessRead(path);
}
}
public async void ProcessRead(filePath)
{
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
最好对大文件使用缓冲 reader。这样的事情会有所帮助。
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
}
}
为什么 BufferedStream 更快
缓冲区是内存中的一个字节块,用于缓存数据,从而减少对操作系统的调用次数。缓冲区提高读写性能。缓冲区可用于读取或写入,但不能同时用于两者。 BufferedStream 的 Read 和 Write 方法自动维护缓冲区。
我有 20 多个文件,每个文件包含近 100 万行(5 GB),我需要加快读取过程,所以我尝试并行读取这些文件,但需要更长的时间时间比顺序阅读它们。有没有办法并行读取非常大的文件?
Parallel.ForEach(sourceFilesList, filePath =>
{
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
StreamReader str = new StreamReader(filePath);
while (!str.EndOfStream)
{
var temporaryObj = new object();
string line = str.ReadLine();
// process line here
}
}
});
它的IO操作,建议像下面这样使用Async/Await(主要使用ReadAsync
函数,有助于异步读取),Async/Await使用你们 Machine Physical Core
的效率很高。
public void ReadFiles()
{
List<string> paths = new List<string>(){"path1", "path2", "path3"};
foreach(string path in Paths)
{
await ProcessRead(path);
}
}
public async void ProcessRead(filePath)
{
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
最好对大文件使用缓冲 reader。这样的事情会有所帮助。
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
}
}
为什么 BufferedStream 更快
缓冲区是内存中的一个字节块,用于缓存数据,从而减少对操作系统的调用次数。缓冲区提高读写性能。缓冲区可用于读取或写入,但不能同时用于两者。 BufferedStream 的 Read 和 Write 方法自动维护缓冲区。