Overwriting byte in binary file, cross-platform?

Dec 25, 2016 at 10:28pm
I figured out how to overwrite a byte (in-place) using 2x file streams ( see: http://stackoverflow.com/questions/6427698/write-to-the-middle-of-an-existing-binary-file-c ), but I just want to be 100% sure that it is OK (cross platform) to have two streams pointing to the same file, opened at the same time, and both read and write to them in an interlaced manner (stream A reads a byte into memory, stream B writes a modified byte to same file, stream A reads next byte, stream B writes modified next byte to same file, etc...).

Maybe a dumb question, but is that defined behavior?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, char** argv) 
{
    // Let's say file contains "abcd"
    std::ifstream fs_in ("test.txt", std::ios::binary | std::ios::in);
    std::fstream  fs_out("test.txt", std::ios::binary | std::ios::out | std::ios::in);
    
    // Start output stream at beginning of file:
    fs_out.seekg(0, fs_in.beg);

    char c;
    for (int i = 0; i < 2; i++) {
        fs_in.read(&c, 1);
        c = toupper(c);
        fs_out.write(&c, 1);     
    }

    // file should now contain "ABcd"
}

Last edited on Dec 25, 2016 at 10:32pm
Dec 25, 2016 at 11:35pm
Why do you need fs_in, when fs_out can both read and write?

Also, you'll get better performance if you read and write in chunks, rather than one byte at a time.
Dec 26, 2016 at 12:17am
Hmm. I think you'll run into trouble because the two streams will use two different streambufs.
Dec 26, 2016 at 3:02am
gaah forum posted error'd my reply. I should just Ctrl-C every time I post...

@helios
Thanks, I changed it to
1
2
3
4
5
6
    for (size_t i = 0; i < filesize; i++) {
        fs_out.read(&c, 1);
        fs_out.putback(c);
        c = some_function(c);
        fs_out.write(&c, 1);     
    }

and got rid of the first stream, and it still exhibits the same correct behavior.

I suppose I could have an array of chars, read in 4x (or something) chars at a time, process them, then write 4x. I would have to handle the case if the last group doesn't evenly divide by 4, but that's another issue for another time. Thanks.

@dhayden
Thanks as well, I tried looking up streambufs inner workings, but that got confusing. But I suppose it's moot for my problem now since I am only going to use one stream.
Last edited on Dec 26, 2016 at 3:03am
Dec 26, 2016 at 4:07am
> I just want to be 100% sure that it is OK (cross platform) to have two streams pointing to the
> same file, opened at the same time, and both read and write to them in an interlaced manner
> (stream A reads a byte into memory, stream B writes a modified byte to same file, stream A
> reads next byte, stream B writes modified next byte to same file, etc...)

This is fine;
The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf<charT,traits> are the same as for reading and writing with the Standard C library FILEs.


If the read/write sequence is anything other than what is mentioned, you may want to tie the streams to each other.
http://en.cppreference.com/w/cpp/io/basic_ios/tie
Topic archived. No new replies allowed.