Go to a specific point in the binary in C (using fseek) and then read from that place (using fread)

I am wondering if this is the best way to solve my problem.

I know the values ​​for the individual offsets of the binary file, which stores the information I want ... I want to do this, go to the offsets, and then read a certain number of bytes, starting from this place.

After using google, I came to the conclusion that it is best to use fseek () to go to the offset position, and then use fread () to read the number of bytes from that position.

Did I understand this correctly? And if so, what is the best way to do this? those. how to combine them together.

If I'm wrong, what would you suggest instead?

Many thanks for your help.

Matt

Edit:

I followed the fread () manual and adjusted it to the following:

`#include <stdio.h> int main() { FILE *f; char buffer[11]; if (f = fopen("comm_array2.img", "rt")) { fread(buffer, 1, 10, f); buffer[10] = 0; fclose(f); printf("first 10 characters of the file:\n%s\n", buffer); } return 0; }` 

So, I used the file "comm_array2.img" and read the first 10 characters from the file.

But from what I understand, this comes from the beginning of the file, I want to go from some place in the file (offset)

Does that make sense?

Change number 2:

It seems that I have faded a bit, and all that is needed (it would seem from my attempt) is to put fseek () in front of fread (), which I have in the code above, and it searches for this place and then reads from there .

+4
source share
3 answers

If you use file streams instead of file descriptors, you can write yourself a (simple) function similar to the POSIX pread() system call.

You can easily emulate it using streams instead of file descriptors 1 . Perhaps you should write yourself a function (which has a slightly different interface from the one I suggested in the comment):

 size_t fpread(void *buffer, size_t size, size_t mitems, size_t offset, FILE *fp) { if (fseek(fp, offset, SEEK_SET) != 0) return 0; return fread(buffer, size, nitems, fp); } 

This is a reasonable compromise between the pread() and fread() conventions.


What would the function call syntax look like? For example, reading from offset 732, and then again from offset 432 (both located at the beginning of the file) and a stream stream called f .

Since you did not say how many bytes to read, I will take 100 every time. I assume that the target variables (buffers) are buffer1 and buffer2 , and that they are both large enough.

 if (fpread(buffer1, 100, 1, 732, f) != 1) ...error reading at offset 732... if (fpread(buffer2, 100, 1, 432, f) != 1) ...error reading at offset 432... 

The returned counter is the number of complete units of 100 bytes each; either 1 (got it all) or 0 (something went wrong).

There are other ways to write this code:

 if (fpread(buffer1, sizeof(char), 100, 732, f) != 100) ...error reading at offset 732... if (fpread(buffer2, sizeof(char), 100, 432, f) != 100) ...error reading at offset 432... 

This reads 100 single bytes each time; The test ensures that you get all 100 of them, as expected. If you take the return value in this second example, you can find out how much data you received. It would be very surprising if the first reading succeeded, and the second failed; some other program (or thread) would have to trim the file between two calls to fpread() , but, as you know, more funny things happened.


1 Emulation will not be perfect; calling pread() provides guaranteed atomicity that the combination of fseek() and fread() does not provide. But this will rarely be a problem in practice if you do not have several processes or threads updating the file at the same time while you are trying to arrange and read it.

+2
source

This often depends on the distance between the parts that interest you. If you just skip / ignore a few bytes between parts that interest you, it is often easier to just read this data and ignore what you are reading, rather than using fseek to skip it. A typical way to do this is to define a structure that stores both the data you care about and the place owners for those you don't care about, read in the structure, and then just use the details you care about:

 struct whatever { long a; long ignore; short b; } w; fread(&w, 1, sizeof(w), some_file); // use 'wa' and 'wb' here. 

If there is any long distance between the parts you care about, it is likely that your original idea to use fseek to get to the parts that matter will be easier.

+1
source

Your theory sounds right. Open, search, read, close.

Create a structure for the data you want to read, and pass a read pointer () to the allocated memory structure. You will probably need #pragma pack (1) or similar in the structure to prevent inconsistency issues.

0
source

Source: https://habr.com/ru/post/1403345/


All Articles