Файл очищен после повторного открытия с помощью std::fstream

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

char* data = new char[5];
std::fstream fs("myFile", std::ios::binary | std::ios::in);//opening with read
fs.read(data, 5);
fs.clear();
fs.close();
//Do some stuff
fs.open("myFile", std::ios::binary | std::ios::out);//opening with write
//The file is already empty at this point

person Community    schedule 07.12.2018    source источник
comment
Как проверить, что файл пустой? Обратите внимание, что если вы открываете файловый поток для записи, содержимое файла уничтожается.   -  person Daniel Langr    schedule 07.12.2018
comment
Если на то пошло, как вы проверяли, что файл заполнен до деструктивного вызова последней строки? Ровно ни одна операция ввода-вывода в этом коде никогда не проверяется. Несмотря на это, вы, кажется, знаете проблему, Но когда я снова открываю файл с разрешениями на запись, все данные внутри очищаются, так что ваш настоящий вопрос Как мне открыть файл файл для записи без уничтожения существующего контента?   -  person WhozCraig    schedule 07.12.2018


Ответы (1)


При открытии файла с флагом записи по умолчанию, т. е. std::ios::out с помощью средства <iostream> или "w" с функциями <cstdio>, за вашей спиной происходит комбинация флагов POSIX — усечение добавлен флаг. Это означает, что при открытии в режиме записи содержимое файла отбрасывается. Чтобы обойти это, откройте файл во второй раз с помощью

fs.open("myFile", std::ios::binary | std::ios::app);

Режим append перемещает файловый курсор в конец файла при каждой операции записи и не сочетается с флагом truncate, см. здесь. Обратите внимание, что если вы хотите записать произвольные позиции в существующем файле, вам нужно открыть его с помощью

fs.open("myFile", std::ios::binary | std::ios::in | std::ios::out);

который не усекает его содержимое и позволяет позиционировать курсор с помощью функций seek*.

person lubgr    schedule 07.12.2018
comment
Поздравляю с 10к. :) - person P.W; 07.12.2018
comment
Но если я открою файл с помощью ios::app, то независимо от того, где я пишу (с любым смещением), данные будут добавлены в конец, а я этого делать не хочу. Итак, как я могу снова открыть файл, не обязательно добавляя данные в конец? - person ; 07.12.2018
comment
Я придумал решение: открыть поток с помощью ios::in и ios::out. Это единственный способ сделать это (как я понял из здесь - person ; 07.12.2018
comment
Правильно, это точно так, как описано в посте, на который я дал ссылку. ios::in | ios::out — значения по умолчанию для конструктора std::fstream. Может быть, я должен также указать это в ответе. - person lubgr; 07.12.2018