我不相信 .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;
}
}
}
这在每次调用时创建缓冲区时效率低下 - 您可能希望创建一次缓冲区并将其传递给方法:
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;
}
}
}
请注意,这也会关闭原始代码未关闭的输出流(由于 using 语句)。
重要的一点是,这将更有效地使用操作系统文件缓冲,因为您重用了相同的输入流,而不是在开始时重新打开文件然后查找。
我认为它会明显更快,但显然你需要尝试一下才能看到......
当然,这假设是连续的块。如果您需要跳过文件的某些部分,您可以从方法外部执行此操作。此外,如果您正在编写非常小的文件,您可能也希望针对这种情况进行优化 - 最简单的方法可能是引入BufferedStream
包装输入流。