reading& writing binary data block by block
hi
i need to write some hex data into a binary file block by block and read it back same as block by block
i try to do it but some error i don't no how to fix this i am stuck i all kind of help appreciated thank u
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string block1 = "DEDEDEDEDEDEDEDEDEDEDED"; // hex data
string block2 = "AFAFAFAFAFAFAFAFAFA"; // hex data
string block3= "BFBFBFBFBFBFBFBFBFBBFBF"; // hex data
string outBlock1;
string outBlock2;
string outBlock1;
fstream file("example.bin", ios::binary | ios::in |ios::out | ios::trunc);
if (!file.is_open()){
cout << "error";
}
else
{
file.write((char *)&block1, sizeof(block1));
file.write((char *)&block2, sizeof(block2));
file.write((char *)&block3, sizeof(block3));
file.read((char *)&indata, sizeof(indata));
/* cout << indata << endl;*/
}
file.close();
return 0;
}
]
Re: reading& writing binary data block by block
block1 etc are of type string so you need
Code:
file.write(block1.c_str(), sizeof(block1));
Note that this does not write the data as hex but as ASCII char the same as set to block1 - so the file contains as text DEDEDE etc. If you want DE to be written as one byte containing the hex number DE then consider
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main() {
const int blksze = 12;
char oblock1[blksze] = { 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE }; // hex data
char oblock2[blksze] = { 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF }; // hex data
char oblock3[blksze] = { 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBB, 0xFB, 0xFB }; // hex data
fstream file("example.bin", ios::binary | ios::in | ios::out | ios::trunc);
if (!file.is_open()) {
cout << "error";
return 1;
}
file.write(oblock1, sizeof(oblock1));
file.write(oblock2, sizeof(oblock2));
file.write(oblock3, sizeof(oblock3));
file.flush();
file.seekg(0);
unsigned char iblock1[blksze] = { 0 };
file.read((char*)iblock1, sizeof(iblock1));
for (int i = 0; i < blksze; ++i)
cout << hex << setw(2) << setfill('0') << (unsigned int)iblock1[i] << " ";
file.close();
return 0;
}
Re: reading& writing binary data block by block
thank u for the help my doubts are almost cleared , what if the block size different and when i read later with only read how can i specify the different size for the blocks , or can i access the block size from the file
Re: reading& writing binary data block by block
Unless you store the block size as part of the file data (or you use a special char to mark block boundaries) you don't know from the file with what block size the file was written. However, the data can be read back from the file using a different block size. In the example, if it was read with a block size of 6 rather than 12 then the first read will obtain the first 6 chars from the file, the next read the next 6 and so on.
Re: reading& writing binary data block by block
now the char initialize manually . char oblock1[blksze] = { 0xDE, 0xDE }; like this
what is the deference between normal char value and this '0x' added .
how can i convert my char or string data to this format '0xDE'
Quote:
Originally Posted by
2kaud
Unless you store the block size as part of the file data (or you use a special char to mark block boundaries)
what u mean by this some one told me all binary data save first size of the block then the block data . i am really confused right now i need examples to understand this binary writing and reading show me how to write two block of data and read that data in other solution
Re: reading& writing binary data block by block
0x means hex notation - so 0xDE means value hex DE which is 13 (D) * 16 + 14 (E) which is decimal 222
The example in post #2 showed how to write /read blocks of binary data.
Quote:
how can i convert my char or string data to this format '0xDE'
If you mean
Code:
string block1 = "DEDEDEDEDEDEDEDEDEDEDED"; // hex data
where does this data originate from? having it produced in the right format first is better than trying to convert.
What exactly are you trying to achieve?
Re: reading& writing binary data block by block
Quote:
The example in post #2 showed how to write /read blocks of binary data.
in example in post #2 all block data have same size what i am trying to achieve is different size of block data( char / string ) need to write into a file then later i need to read back
what if i use a for loop to fill this (char block[size]) then how can i convert normal char '0x' hex notation char
Re: reading& writing binary data block by block
Lets take a step back here. What are you trying to do - why do you want to read/write different size of block data, what data are you storing in the file, where's it coming from?
Quote:
convert normal char '0x' hex notation char
the 0x notation is just used when referencing a hex number in a program. Instead of using 222 (as a decimal number), this can be written 0xDE
Code:
int a = 0;
a += 222;
a += 0xDE;
In both cases above, a is incremented by the same value 222.
Re: reading& writing binary data block by block
For an example of reading/writing variable length binary data consider
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <memory>
using namespace std;
union num {
int n;
unsigned char c[sizeof(int)];
};
fstream& write(fstream& is, const unsigned char *const bl, int sz)
{
num n;
n.n = sz;
is.write((char*)n.c, sizeof(n.c));
is.write((char*)bl, n.n);
return is;
}
fstream& read(fstream& os)
{
num n;
os.read((char*)n.c, sizeof(n.c));
auto bl = make_unique<unsigned char[]>(n.n);
os.read((char*)bl.get(), n.n);
for (int i = 0; i < n.n; ++i)
cout << hex << setw(2) << setfill('0') << (unsigned int)(bl.get())[i] << " ";
cout << endl;
return os;
}
int main() {
unsigned char oblock1[] = { 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE }; // hex data
unsigned char oblock2[] = { 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF }; // hex data
unsigned char oblock3[] = { 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBB, 0xFB, 0xFB }; // hex data
fstream file("example.bin", ios::binary | ios::in | ios::out | ios::trunc);
if (!file.is_open()) {
cout << "error";
return 1;
}
write(file, oblock1, sizeof(oblock1));
write(file, oblock2, sizeof(oblock2));
write(file, oblock3, sizeof(oblock3));
file.flush();
file.seekg(0);
read(file);
read(file);
read(file);
file.close();
return 0;
}
Re: reading& writing binary data block by block
yes that's all i want i got it . some area in the code i didn't understand
Code:
union num {
int n;
unsigned char c[sizeof(int)];};
Code:
os.read((char*)n.c, sizeof(n.c));
auto bl = make_unique<unsigned char[]>(n.n);
os.read((char*)bl.get(), n.n);
thank you
Re: reading& writing binary data block by block
The elements of a union occupy the same memory locations but can be referenced in different ways. Here an int and a 4 byte char array occupy the same memory so setting .n to say 20 then the individual bytes of the number as held in memory can be accessed by the .c so that they can be written to the file.
For the read, the first line reads the first 4 bytes into the union as .c which then has .n the number of bytes to read. make_unique sets bl to a unique_ptr (see http://www.cplusplus.com/reference/memory/unique_ptr/) memory allocation. Then the required number of bytes is read from the file into the memory. As bl is managed memory, it is automatically freed when the function ends so you don't need additional delete statements.