Использование FileStream.SetLength()
будет примерно таким же быстрым, как вы можете это сделать.
В итоге вызывается API Windows для установки длины файла, такой же, как std::filesystem::resize_file()
.
Так что вам просто нужно сделать что-то подобное, и это будет достаточно быстро:
using (var file = File.Open(myFilePath, FileMode.Open))
{
file.SetLength(myRequiredFileSize);
}
Реализация FileStream.SetLength ():
private void SetLengthCore(long value)
{
Contract.Assert(value >= 0, "value >= 0");
long origPos = _pos;
if (_exposedHandle)
VerifyOSHandlePosition();
if (_pos != value)
SeekCore(value, SeekOrigin.Begin);
if (!Win32Native.SetEndOfFile(_handle)) {
int hr = Marshal.GetLastWin32Error();
if (hr==__Error.ERROR_INVALID_PARAMETER)
throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_FileLengthTooBig"));
__Error.WinIOError(hr, String.Empty);
}
// Return file pointer to where it was before setting length
if (origPos != value) {
if (origPos < value)
SeekCore(origPos, SeekOrigin.Begin);
else
SeekCore(0, SeekOrigin.End);
}
}
(Обратите внимание, что SeekCore()
просто вызывает функцию Windows API SetFilePointer()
.)
Это НЕ считывает файл в память.
Кроме того, функция Windows API SetEndOfFile()
не пишет в расширенную область, поэтому это быстро. Документация гласит If the file is extended, the contents of the file between the old end of the file and the new end of the file are not defined.
- это результат того, что данные не записываются в расширенную область.
В качестве теста я попробовал следующий код:
using System;
using System.Diagnostics;
using System.IO;
namespace Demo
{
public class Program
{
public static void Main()
{
string filename = @"e:\tmp\test.bin";
File.WriteAllBytes(filename, new byte[0]); // Create empty file.
var sw = Stopwatch.StartNew();
using (var file = File.Open(filename, FileMode.Open))
{
file.SetLength(1024*1024*1024);
}
Console.WriteLine(sw.Elapsed);
}
}
}
My E: \ диск это жесткий диск, а не SSD.
Вывод был: 00:00:00.0003574
Таким образом, расширение файла до 1 ГБ заняло не более сотни секунд.