Функция записи не использует значение поиска - PullRequest
4 голосов
/ 28 октября 2011

Я пытаюсь использовать C ++ для записи записи в определенном месте файла

так что в основном у меня есть

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

Но что бы я ни делал, всегда пишите в конце файла.

Полагаю, это связано с iso::app, поскольку согласно документации

app (append) Set the stream's position indicator to the end of the stream before each output operation

Но если я использую съел или ничего, он всегда стирает содержимое файла.

Любая помощь будет великолепна:)

Ответы [ 3 ]

5 голосов
/ 28 октября 2011

Да, именно ios::app вызывает такое поведение. Замените его на ios::in | ios::out.

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

2 голосов
/ 28 октября 2011

Режим добавления файла

Если ОС (и сетевая файловая система, если применимо) поддерживает режим добавления, установка режима добавления гарантирует, что записанные данные не перезаписывают существующие данные в файле, когдаЕсть несколько авторов.Это то, что вы не можете сделать без режима добавления, из-за гонки между поиском и записью из разных процессов.Это важная гарантия для файлов журнала.

В режиме добавления вы можете писать только в конце файла по определению.

Режимы открытия Iostream

Согласно [ofstream.cons], ofstream (s, mode) вызывает rdbuf()->open(s, mode|ios_base::out).

Согласно таблице "Режимы открытия файлов" в [filebuf.members], поведение filebuf::open определяется в терминах fopen режимов открытия:

  • out означает «w»
  • app и app|out означает «a»
  • in|out означает «r +»
  • in|out|trunc означает «w +»

В соответствии с fopen man режимы означают:

  • r + Открыть для чтения и записи.
  • w Обрезать файл до нулевой длины или создать текстовый файл для записи.
  • w + Открыть для чтения и записи.Файл создается, если он не существует, в противном случае он усекается.
  • a Открыть для добавления (запись в конце файла).Файл создается, если он не существует.

Наконец, ate означает fseek(file,0,SEEK_END).

Итак, если вы хотите открыть для записи в произвольной позиции, не разрушаясуществующие данные, вам нужно fopen(s,"r+") или ofstream (s, ios::in|ios::out).

IOW, в C / C ++ вам также необходим доступ на чтение к файлу, чтобы открыть его для записи без перезаписи!

POSIXworld

Вы можете вместо этого использовать функцию POSIX open, чтобы получить прямой доступ к флагам открытия POSIX: O_READ, O_WRITE, O_CREAT, O_EXCL, O_TRUNC... Они не только намного более мощные, но также независимые ортогональные флаги и хорошо себя ведут, в отличие от filebuf::open флагов.

Конечно, эта функция не является частью стандартного C ++.Я считаю, что все системы, относящиеся к нормальному программированию (не специализированные рынки с особыми характеристиками), поддерживают open.

1 голос
/ 28 октября 2011

Вы пытались использовать ios::out вместо ios::app?

РЕДАКТИРОВАТЬ:

После прочтения документов, на которые ссылается @curiousguy, похоже, что вам нужно ios::in | ios::out вместо ios::out, чтобы избежать усечения.

...