C ++ замена ios :: noreplace - PullRequest
       26

C ++ замена ios :: noreplace

2 голосов
/ 12 февраля 2012

Я использую fstream, чтобы открыть файл для записи. Я не хочу перезаписывать существующий файл, поэтому после некоторого поиска я нашел ios :: noreplace. Но когда я компилирую это:

#include <fstream>
using namespace std;
//......Did something else.
ofstream fout;
fout.open(outputFile,ios::noreplace);//outputFile is a C string

Я получаю ошибку

 error: ‘noreplace’ is not a member of ‘std::ios’

Мне просто интересно, есть ли std :: subsitution для ios :: noreplace?

Ответы [ 3 ]

6 голосов
/ 12 февраля 2012

Некоторые поиски в Интернете показывают, что вы можете добавить проверку существования вручную, пытаясь открыть в режиме «ввода»:

std::fstream myfile("thefile.txt", std::ios::in);

if (myfile)
{
    // error, file exists!
}
else
{
    myfile.close();
    myfile.open("thefile.txt", std::ios::out);  // OK now
}
4 голосов
/ 12 февраля 2012

noreplace никогда не попал в стандарт.Около четырех секунд поиска в Google: http://www.devx.com/tips/Tip/14544

В предварительном стандарте C ++ некоторые реализации предлагали флаги ios :: nocreate и ios :: noreplace для управления созданием файла.Эти флаги были слишком специфичны для платформы и никогда не входили в стандартную библиотеку, которая заменяет устаревший предварительно стандартный заголовок.Тем не менее, вы можете легко достичь функциональности этих устаревших флагов.

fstream fs(fname, ios_base::in);// attempt open for read
if (!fs)
{
    // file doesn't exist; create a new one
    fs.open(fname, ios_base::out);
}
else //ok, file exists; close and reopen in write mode
{
     // Should throw an error
}
3 голосов
/ 01 августа 2016

Предлагаемые ответы рискованны, так как имеют гоночные условия.Если вы не можете гарантировать, что никто никогда не создаст этот файл, пока вы выполняете этот тест, вы не должны использовать его.

В качестве обходного пути используйте непереносимый метод (в Linux, например, открыть с помощью O_CREAT | O_EXCL).

Вы можете использовать результирующий дескриптор с кодом, например, boost, чтобы обернуть его в ofstream, или в этом случае использовать open () только для проверки, а затем создать новый ofstream в файле (последний не предполагает, что никтоудаляет / переименовывает промежуточный файл и, таким образом, может по-прежнему иметь состояние гонки).

C ++, не обеспечивающий ЛЮБОГО безопасного способа создания файла, - плохая шутка и, вероятно, причина многих пробелов в безопасности.Вы должны любить стандарты, которые поощряют плохие практики, делая невозможным написание правильного кода.

...