Я заметил, что std::ofstream
иногда не удается открыть существующие файлы. После небольшого исследования я обнаружил, что проблема зависит от размера открываемого файла.
Например, я использовал следующий код, чтобы попытаться открыть файлы около отметки 4 ГиБ:
#include <fstream>
#include <iostream>
#include <memory>
constexpr size_t operator ""_MiB(unsigned long long i)
{
return i * 1024 * 1024;
}
constexpr size_t operator ""_GiB(unsigned long long i)
{
return i * 1024 * 1024 * 1024;
}
int main(int argc, char* argv[])
{
for (size_t fileSize {4_GiB - 3_MiB}; fileSize < 4_GiB + 12_MiB; fileSize += 1_MiB)
{
remove("test.raw");
std::ofstream os {"test.raw", std::ofstream::binary};
std::unique_ptr<char[]> buffer {std::make_unique<char[]>(fileSize)};
os.write(buffer.get(), fileSize);
os.close();
std::ofstream os1 {"test.raw", std::ofstream::binary};
std::cout << fileSize / 1_MiB << " MiB os1.good(): " << os1.good() << std::endl;
os1.close();
}
}
Вывод:
4093 MiB os1.good(): 1
4094 MiB os1.good(): 1
4095 MiB os1.good(): 1
4096 MiB os1.good(): 0
4097 MiB os1.good(): 0
4098 MiB os1.good(): 0
4099 MiB os1.good(): 0
4100 MiB os1.good(): 0
4101 MiB os1.good(): 0
4102 MiB os1.good(): 0
4103 MiB os1.good(): 0
4104 MiB os1.good(): 1
4105 MiB os1.good(): 1
4106 MiB os1.good(): 1
4107 MiB os1.good(): 1
Это удивляет меня, так как я подумал, что открытие существующего файла с ofstream
должно было обрезать этот файл, что он делает для успешных размеров файлов. fstream
показывает то же поведение, если файл открывается с fstream::trunc
или без fstream::in
. В противном случае открытие сбойных файлов с помощью fstream
или ifstream
работает просто отлично.
Я понимаю, что сначала могу просто удалить файл, как в примере выше, а затем использовать ofstream
для создания новогофайл, но я бы скорее понял, что вызывает такое поведение, и если я могу избавиться от него.
Я нахожусь на Windows 10, компилируя с некоторой версией msvc 2015 для C ++ 14.
Есть ли разумная причина такого поведения? Что вызывает это?