Reading/Writing partial bytes to files... c++
I'm trying to be able to read and write partial bytes from files, either using some kind of offset method (like tacking on a extra bit or two to make a complete byte), or just writing something like n bits at a time.
So far it looks like using a offset method is the only way to get it working; I'm using <fstream> write functions, and as far as I know, they don't allow anything smaller then a byte to be written.
So I'm using vector<unsigned char> array to store the individual partial bytes. Is there a nice, clean method of writting only the first n bits of each byte to a file? Or can I copy them over to a different byte array without the trailing bit(s)?
Example: Using only 7 bits of the byte
vector<unsigned char> arrayOffset;
Byte 1:
110101|0
Byte 2:
110110|0
To a more compressed form:
vector<unsigned char> arrayCompressed;
Byte 1:
1101011
Byte 2:
10110|00
This would save a byte for every 8 bytes required.
Reading this into a useful format would also be a problem. I'd need to be able to step through the chunk of data on the bit level.
Any ideas on how to solve this would be greatly appreciated.
Encode the data before writing it. You simply can not address less than a byte: manipulating bits requires loading up at least a byte and then applying masks or binary operations. if you're employing 7-bit data chunks, then read/write eight of them at a time (for a total of seven bytes).
Also, consider std::vector<bool> instead of std::vector<unsigned char>. Let me know if you need further clarification.
Also, consider std::vector<bool> instead of std::vector<unsigned char>. Let me know if you need further clarification.
I don't understand what you mean by encoding the data. I think I understand what you meant by not working with anything smaller then a byte. In this particular case, I was planning on writing c amount of n bit chuncks of data. Constant c can be any number, while the constant n can be between 1 and 32.
After a bit of testing, I've been able to write an array of bools to a file with the desired results. Now I just need to transulate between a vector<unsigned int> to a vector<bool> using the first n bits of the int. Hrm.
After a bit of testing, I've been able to write an array of bools to a file with the desired results. Now I just need to transulate between a vector<unsigned int> to a vector<bool> using the first n bits of the int. Hrm.
What are you attempting to read in again? The smallest piece that you can handle is a single byte, and nothing smaller than that. A single byte is often represented by the char (or unsigned char) data type. The boolean data type (as long as it is native to the compiler) is a single byte as well.
You can read in a single byte from a file like the following:
That might be a little bit off (I haven't worked with binary files in a little while) but you should get the basic concept of the idea. The same can be done with C-style file operations:
Once again, the basic idea, I haven't used binary files in C a lot longer than I have in C++ ;). I hope this helps a little bit! You could Google it a little more if you wish, there are some awesome tutorials on binary file formats that I believe any programmer should definately get used to (I've been slacking, but I'll be working on that soon enough).
note: I assumed you were working in binary files, but if you're not, you could still work the same way (but I don't see the point).
You can read in a single byte from a file like the following:
void main(void){ std::ifstream fi("path/to/file.dat",std::ios::binary); // need to make sure that the file is open in order to handle it if(fi.is_open()) { fi.seekg(0,std::ios_base::beg); // start at the beginning of the file (no offests) char single = ''; fi.read( single, sizeof( char ) ); } fi.close();}
That might be a little bit off (I haven't worked with binary files in a little while) but you should get the basic concept of the idea. The same can be done with C-style file operations:
void main(void){ FILE* fi = fopen("path/to/file.dat","r"); // need to make sure that the file is open in order to handle it if(fi) { fseek(fi,0,SEEK_SET); // start at the beginning of the file (no offests) char single=''; fread(&single,sizeof(char),1,fi); } fclose( fi ); fi = 0;}
Once again, the basic idea, I haven't used binary files in C a lot longer than I have in C++ ;). I hope this helps a little bit! You could Google it a little more if you wish, there are some awesome tutorials on binary file formats that I believe any programmer should definately get used to (I've been slacking, but I'll be working on that soon enough).
note: I assumed you were working in binary files, but if you're not, you could still work the same way (but I don't see the point).
You are quite correct, that code should read a single byte from a file. However, it looks like I'm composing my data, whether byte aligned (bits divisiable by 8) or not, into one long chunk + bits needed to complete last byte. The problem I'm facing now, is to get the data into the long chunk.
An array of bools can be used to write out individual bits, but it completes the byte on them, making a huge waste of space.
An array of bools can be used to write out individual bits, but it completes the byte on them, making a huge waste of space.
Quote:Original post by Mawr
You are quite correct, that code should read a single byte from a file. However, it looks like I'm composing my data, whether byte aligned (bits divisiable by 8) or not, into one long chunk + bits needed to complete last byte. The problem I'm facing now, is to get the data into the long chunk.
I'm not understanding this part. There are 8 bits in a byte, yes, but the smallest unit you can use is a byte. You can (theroetically) divide a byte up into smaller pieces, but the smallest unit of measure possible (that you can handle) is a byte. Are you talking about offsets and how you can get to a single piece of data without reading in the rest of the data first?
Composing boolean values into the bits of another data type (eg. int, char) is just a matter of the shift operator and boolean operators. Generally you want to build up a value by OR-ing the storage variable with your boolean variable, which has been suitably shifted to line up with the relevant bits in the storage variable.
Alternatively, give up if you're only saving 1 byte out of 8. That sort of saving probably isn't even worth it on embedded systems.
Alternatively, give up if you're only saving 1 byte out of 8. That sort of saving probably isn't even worth it on embedded systems.
I'll try to get it working using the OR operator. For extraction, I guess I have to use the AND operator? I'll see if I can get that far.
The reason I'm trying to save as many bits as possible is I'm writing a .bmp image compression program. So far it's been working ok, but it has a harsh limitation. It can only have 255 unique colors spread across the image files you wish to compress into one. I'm not going to bore you guys with the exact details (not until I get it completly working in the specification I want :) ), but being able to work with n bit data chunks will allow to work with 1 through 2^32 colors, and saving harddisk space appropriatly.
The reason I'm trying to save as many bits as possible is I'm writing a .bmp image compression program. So far it's been working ok, but it has a harsh limitation. It can only have 255 unique colors spread across the image files you wish to compress into one. I'm not going to bore you guys with the exact details (not until I get it completly working in the specification I want :) ), but being able to work with n bit data chunks will allow to work with 1 through 2^32 colors, and saving harddisk space appropriatly.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement