tags:

views:

475

answers:

4

When I do

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

It seems to replace the entire file with those 100 bytes instead of replacing only the appropriate 100 bytes, as if I had specified ios::trunc. Is there a portable way to not have it truncate the file?

Edit: adding ios::in seems to do the trick, by why is this required, and is that standard behavior?

Edit #2: I am not trying to append to the existing file. I need to replace the 100 bytes while leaving the rest unaffected.

+1  A: 

AFAIR ios::out only specifies the file is for output and ios:binary only specifies the files is binary. The default behaviour for a stream is to create a new file and overwrite the old file. If you want to modify an existing file you must open the file with the ios::app flag.

ATM I cannot check my references so be sure to double check, but I felieve that is accurate.

BubbaT
A: 

The ios:in mask tells the file pointer to position at the beginning of the file so it can start reading in from the start. But, you may want to use fseek to set the file pointer at the beginning of the file.

Azder
+2  A: 

You want the append flag, ios::app, if you want to write at the end of the file.

To do it somewhere arbitrarily in the middle of the file, you need to seek to the right place. You CAN do this by opening the file for in and out, but if I were you I'd create a temp file, copy input up to mark, write your new data, copy the rest to EOF, close the files and replace the previous version with the temp file. This is called a "Master File update".

Charlie Martin
Sydius
the in and out is standard, it's just hard to get the code right. It's somewhat easier with record-oriented, or fixed format, data, but the default way of doing IO in C-like languages is variable length text-based records, or pure binary. So if you get sizes or offsets wrong, or you have multiple writers, you can mung the whole file. If you do a master file update you at least should end up with a file that's internally consistent.
Charlie Martin
A: 

Since the file already exists open it in 'read+write' mode and then do seekp. I think it will work.

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