Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a binary file 1 byte at a time

Tags:

c

file

io

binary

I am trying to read a binary file in C 1 byte at a time and after searching the internet for hours I still can not get it to retrieve anything but garbage and/or a seg fault. Basically the binary file is in the format of a list that is 256 items long and each item is 1 byte (an unsigned int between 0 and 255). I am trying to use fseek and fread to jump to the "index" within the binary file and retrieve that value. The code that I have currently:

unsigned int buffer;

int index = 3; // any index value

size_t indexOffset = 256 * index;
fseek(file, indexOffset, SEEK_SET);
fread(&buffer, 256, 1, file);

printf("%d\n", buffer);

Right now this code is giving me random garbage numbers and seg faulting. Any tips as to how I can get this to work right?

like image 423
RogerB Avatar asked May 23 '11 05:05

RogerB


2 Answers

Your confusing bytes with int. The common term for a byte is an unsigned char. Most bytes are 8-bits wide. If the data you are reading is 8 bits, you will need to read in 8 bits:

#define BUFFER_SIZE 256

unsigned char buffer[BUFFER_SIZE];

/* Read in 256 8-bit numbers into the buffer */
size_t bytes_read = 0;
bytes_read = fread(buffer, sizeof(unsigned char), BUFFER_SIZE, file_ptr);
// Note: sizeof(unsigned char) is for emphasis

The reason for reading all the data into memory is to keep the I/O flowing. There is an overhead associated with each input request, regardless of the quantity requested. Reading one byte at a time, or seeking to one position at a time is the worst case.

Here is an example of the overhead required for reading 1 byte:

Tell OS to read from the file.
OS searches to find the file location.
OS tells disk drive to power up.
OS waits for disk drive to get up to speed.
OS tells disk drive to position to the correct track and sector.
-->OS tells disk to read one byte and put into drive buffer.
OS fetches data from drive buffer.
Disk spins down to a stop.
OS returns 1 byte to your program.

In your program design, the above steps will be repeated 256 times. With everybody's suggestion, the line marked with "-->" will read 256 bytes. Thus the overhead is executed only once instead of 256 times to get the same quantity of data.

like image 188
Thomas Matthews Avatar answered Sep 21 '22 02:09

Thomas Matthews


In your code you are trying to read 256 bytes to the address of one int. If you want to read one byte at a time, call fread(&buffer, 1, 1, file); (See fread).

But a simpler solution will be to declare an array of bytes, read it all together and process it after that.

like image 45
MByD Avatar answered Sep 24 '22 02:09

MByD