Jump to content
  • Advertisement
Sign in to follow this  
Mawr

Reading/Writing partial bytes to files... c++

This topic is 4848 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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:

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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!