c++ binary files

Hi,

I have been searching online for examples on how to write binary files in c++ but the only example I was able to find was about reading a binary file.

http://www.cplusplus.com/doc/tutorial/files/

I would appreciate it if you can direct me to complete examples of writing to binary files.

If nothing is available, I wish you can clarify a few things please:

1. How to know how much of the buffer is filled?

2. Do you write to disk as part of the data arrive? Or wait for the buffer to become full before you write?

3. what if it overflows?

4. will buffer be reset automatically after each write to the beginning of the buffer?

Thank you very much
Last edited on
1) In general, you don't know or care. The ofstream object takes care of flushing the buffer when necessary.

2) You write to the stream. Again, you don't know or care when the buffer is flushed since it is done automatically when needed.

3) Won't happen as it gets flushed when full.

4) The buffer is generally implemented as a circular buffer. See my explanation below for an example of what happens when the buffer is flushed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Writing a binary file
#include <iostream>
#include <fstream>
using namespace std;

int main () 
{   const int size = 1000; 
    char memblock[size];

    ofstream file ("example.bin", ios::binary|ios::ate);
    if (! file.is_open())
    {   cout << "Unable to open file" << endl;
        return 1;
    }
    memset (memblock, 'A', size);   
    file.write (memblock, size);
    file.close();
    return 0;
}


In the above example, let's assume ofstream's buffer size is 512 bytes. The write at line 16 will physically write 512 bytes to the disc and leave 488 bytes in the buffer. When the file is closed, the remaining 488 bytes will be written to the disc. The size of the buffer is implementation dependent and may be something other than 512 bytes I used in this example. The actual size of the buffer makes no difference to your program.
Last edited on
Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "tempwriter.h"
#include <iostream>


int TempWriter::bufferSize = 10;

TempWriter::TempWriter()
{
    tempFile.open("C:\\binary test\\test.bin", std::ios::out | std::ios::binary | std::ios::ate);

    if(!tempFile.is_open())
    {
        exit(1);
    }

    memblock = new char[TempWriter::bufferSize];
}

TempWriter::~TempWriter()
{
    tempFile.close();
    delete[] memblock;
}

void TempWriter::temporaryWrite(std::string line)
{
    if(tempFile.good())
    {
        memset (memblock, line , line.length());
        tempFile.write (memblock, line.length());
    }
    else
    {
        //THROW EXCEPTION
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>

#include "tempwriter.h"

int main(int argc, char *argv[])
{
    TempWriter temp;
    std::string first = "1st line \n";
    temp.temporaryWrite(first);
    std::string second = "2nd line \n";
    temp.temporaryWrite(second);
    std::string third = "3rd line \n";
    temp.temporaryWrite(third);


    return 0;
}


I don't seem to get it to compile because I get error: 'memset' was not declared in this scope
memset (memblock, line , line.length());

Also, if this is the correct implementation, is it efficient?
^
closed account (E0p9LyTq)
WhatIf wrote:
I don't seem to get it to compile because I get error: 'memset' was not declared in this scope
memset (memblock, line , line.length());

Have to include the <cstring> header to use std::memset.

Using C string functions when using C++ STL strings is going to be inefficient at best.
You need to #include <stdio.h>
memset (memblock, line , line.length());
You also need to be careful that line.length is not > 9;

Much easier would be:
1
2
3
4
5
6
7
8
9
10
11
void TempWriter::temporaryWrite(std::string line)
{
    if(tempFile.good())
    {
        tempFile.write (line.data(), line.length());
    }
    else
    {
        //THROW EXCEPTION
    }
}
You didn't show tempwriter.h, so I can only guess at your class declaration.

tempwriter.cpp line 29: you have no protection of line.length() exceeding the size of memblock.
I also don't think you want to use memset here. memset sets all characters of the buffer to the second argument. Did you intend memcpy?

Why not eliminate line 29 and just use this at line 30:
 
  tempFile.write (line.c_str(), line.length());

No need for memblock at all.



Last edited on
2 last clarifications please:

Everywhere I read they mention the need for read/write buffers. Is that wrong? Or does the line.c_str() in

tempFile.write (line.c_str(), line.length());

creates a buffer in the background?

I fell that this approach is much safer as I don't have to worry about buffer overflow.

From the c_str() reference
This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null-character ('\0') at the end.


Does that mean that the null-character ('\0') is written to disk?
> Does that mean that the null-character ('\0') is written to disk?
Very often, no. If you specify the length that includes the null character as well, yes it will work :
tempFile.write (line.c_str(), line.length() + 1);
Topic archived. No new replies allowed.