ala*_*ala 39 c# cpu streaming performance utilization
我必须将一个巨大的文件拆分成许多较小的文件.每个目标文件由偏移量和长度定义为字节数.我正在使用以下代码:
private void copy(string srcFile, string dstFile, int offset, int length)
{
BinaryReader reader = new BinaryReader(File.OpenRead(srcFile));
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
byte[] buffer = reader.ReadBytes(length);
BinaryWriter writer = new BinaryWriter(File.OpenWrite(dstFile));
writer.Write(buffer);
}
Run Code Online (Sandbox Code Playgroud)
考虑到我必须将此功能调用大约100,000次,因此速度非常慢.
Jon*_*eet 46
我不相信.NET中有任何东西允许复制文件的一部分而不在内存中缓冲它.然而,无论如何,这对我来说是低效的,因为它需要打开输入文件并多次搜索.如果您只是拆分文件,为什么不打开输入文件一次,然后只写下:
public static void CopySection(Stream input, string targetFile, int length)
{
byte[] buffer = new byte[8192];
using (Stream output = File.OpenWrite(targetFile))
{
int bytesRead = 1;
// This will finish silently if we couldn't read "length" bytes.
// An alternative would be to throw an exception
while (length > 0 && bytesRead > 0)
{
bytesRead = input.Read(buffer, 0, Math.Min(length, buffer.Length));
output.Write(buffer, 0, bytesRead);
length -= bytesRead;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这在每次调用时创建缓冲区的效率很小 - 您可能希望创建一次缓冲区并将其传递给方法:
public static void CopySection(Stream input, string targetFile,
int length, byte[] buffer)
{
using (Stream output = File.OpenWrite(targetFile))
{
int bytesRead = 1;
// This will finish silently if we couldn't read "length" bytes.
// An alternative would be to throw an exception
while (length > 0 && bytesRead > 0)
{
bytesRead = input.Read(buffer, 0, Math.Min(length, buffer.Length));
output.Write(buffer, 0, bytesRead);
length -= bytesRead;
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这也会关闭原始代码没有的输出流(由于using语句).
重要的是,这将更有效地使用操作系统文件缓冲,因为您重用相同的输入流,而不是在开始时重新打开文件然后寻求.
我认为它会明显加快,但显然你需要尝试看看......
当然,这假定是连续的块.如果您需要跳过文件的位,可以从方法外部执行此操作.此外,如果您正在编写非常小的文件,您可能也希望针对该情况进行优化 - 最简单的方法可能是引入BufferedStream包装输入流.
Bob*_*yan 26
从C#执行文件I/O的最快方法是使用Windows ReadFile和WriteFile函数.我编写了一个C#类来封装这个功能,以及一个查看不同I/O方法的基准测试程序,包括BinaryReader和BinaryWriter.请参阅我的博文:
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp/
有多大length?您可以更好地重复使用固定大小(中等大小但不淫秽)的缓冲区,并忘记BinaryReader...只需使用Stream.Read和Stream.Write.
(编辑)类似于:
private static void copy(string srcFile, string dstFile, int offset,
int length, byte[] buffer)
{
using(Stream inStream = File.OpenRead(srcFile))
using (Stream outStream = File.OpenWrite(dstFile))
{
inStream.Seek(offset, SeekOrigin.Begin);
int bufferLength = buffer.Length, bytesRead;
while (length > bufferLength &&
(bytesRead = inStream.Read(buffer, 0, bufferLength)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
length -= bytesRead;
}
while (length > 0 &&
(bytesRead = inStream.Read(buffer, 0, length)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
length -= bytesRead;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94800 次 |
| 最近记录: |