2

I want to use fread or something similar in a strange way. I am not sure whether it is possible or not... Let me explain the case:

I have a binary file, named "dummy". This file contains unsigned char array in it. However, I want to take them into a float array which will store 4x memory space.

I can achieve my goal like the following:

FILE* in_file;
int numberOfCharacters = 1000; // number of unsigned characters to read ...
in_file = fopen("dummy", "rb");

float* floatArray = (float*) malloc( numberOfCharacters * sizeof(float) );

for(int i=0;i<numberOfCharacters;i++)
{
    unsigned char temp;
    fread(&temp, sizeof(unsigned char), 1, in_file);
    floatArray[i] = temp;
}

I know (actually didn't really try) this way will probably work. But I'm curious whether is there a better (faster) way of doing it? Maybe, without a loop..?

Thanks in advance,

Sait.

Sait
  • 19,045
  • 18
  • 72
  • 99
  • 2
    what's so strange? btw: to me it seems a C question – BigMike May 04 '12 at 12:52
  • You may run into issues if the endianness doesn't match between the source of the binary file and the destination (where it is being read) and the writing/reading process doesn't take care of that. – dirkgently May 04 '12 at 12:55
  • The length of unsigned character array that I have is a little big. So, any improvement will be very helpful. – Sait May 04 '12 at 12:56
  • Also, possible dup of http://stackoverflow.com/questions/1422817/how-to-read-a-float-from-binary-file-in-c. – dirkgently May 04 '12 at 12:57
  • @dirkgently There is no endianness issue since he is reading `unsigned char`s and then casting them to `float`s. – IronMensan May 04 '12 at 13:24
  • @IronMensan: One-byte floats? That looks strange to me. – dirkgently May 04 '12 at 13:53
  • I'm very curious as to the reason you'd want to read in individual bytes & store them in an array as floats. – phonetagger May 04 '12 at 14:46

3 Answers3

2

The example appears like it is okay (although some error checking might be good). One possible performance improvement might be to move the fread prior to the loop and read all 1000 entries at one time (into an allocated char array). But that would probably be only slightly faster since fread is buffered.

Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
1

Off the cuff:

  • You may run into issues if the endianness doesn't match between the source of the binary file and the destination (where it is being read) and the writing/reading process doesn't take care of that.
  • Look up setvbuf to set buffering mode for your file.
  • You may also want to look at memory-mapped files (mmap)
  • This is much easier in C++ using fstream (file-streams) and iterators (i.e. syntactically). Further, if you want performance, you can create your own optimized file stream by overriding the appropriate members.
  • For further reading look up filtering streambufs too

Minor nits:

  • In C, you don't need to cast the return value of malloc
  • #include proper headers
  • Test if fopen succeeded or not and then close the file once done
  • Deallocate your floatarray once done
dirkgently
  • 108,024
  • 16
  • 131
  • 187
0

Checking the returned value from fread for EOF will avoid extra looping and possibly filling the rest of floatArray with garbage

you can also get the size of the file with

fseek (in_file, 0, SEEK_END);
size=ftell (in_file);

If you want to allocate less memory for the float array

msam
  • 4,259
  • 3
  • 19
  • 32