メモリにバッファリングせずにファイルのセクションをコピーできるようにするものが .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
入力ストリームのラッピングを導入することです。