2009-04-27 4 views
1

Когда яfstream заменить часть файла

fstream someFile("something.dat", ios::binary|ios::out); 
someFile.seekp(someLocation, ios::beg); 
someFile.write(someData, 100); 

Кажется, заменить весь файл с этих 100 байт вместо замены только соответствующие 100 байт, как если бы я указано Ios :: TRUNC. Есть ли переносимый способ не обрезать файл?

Редактировать: Добавление ios :: in похоже на трюк, почему это необходимо, и является ли это стандартным поведением?

Редактировать # 2: Я не пытаюсь добавить существующий файл. Мне нужно заменить 100 байт, оставив остальное без изменений.

ответ

2

Вам нужен флаг append, ios :: app, если вы хотите записать в конце файла.

Чтобы сделать это где угодно произвольно в середине файла, вам нужно искать нужное место. Вы можете сделать это, открыв файл для входа и выхода, но если бы я был вами, я бы создал временный файл, скопировал ввод до отметки, напишу ваши новые данные, скопировал остальные в EOF, закрою файлы и заменил предыдущий версии с временным файлом. Это называется «Обновление основного файла».

+0

Является ли in & out нестандартным или вы предлагаете этот альтернативный метод безопасности данных? – Sydius

+0

вход и выход стандартно, просто получить код в порядке. Это несколько проще с записью или фиксированным форматом данных, но способ ввода IO по умолчанию на языках C-типа - это текстовые записи переменной длины или чистые двоичные файлы. Поэтому, если вы ошиблись в размерах или смещениях, или у вас есть несколько авторов, вы можете перетащить весь файл. Если вы сделаете обновление основного файла, вы, по крайней мере, должны получить файл, который будет внутренне непротиворечивым. –

2

AFAIR ios :: out определяет только файл для вывода, а ios: двоичный код указывает только бинарные файлы. Поведение по умолчанию для потока - это создать новый файл и перезаписать старый файл. Если вы хотите изменить существующий файл, вы должны открыть файл с флагом ios :: app.

ATM Я не могу проверить свои ссылки, поэтому не забудьте дважды проверить, но я верю, что это точно.

1

ios: in mask указывает указателю на файл в начале файла, чтобы начать чтение с самого начала. Но вы можете использовать fseek для установки указателя файла в начале файла.

2

Поскольку файл уже существует, откройте его в режиме «читать + писать», а затем выполните поиск. Я думаю, это сработает.

fstream someFile("something.dat", ios::binary|ios::out|ios::in); 
someFile.seekp(someLocation, ios::beg); 
someFile.write(someData, 100); 
Смежные вопросы