Я не верю, что в .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
, обертывающий поток ввода.