0

I have some binary data in a file. In order to read all the data, I did this:

// open the file
// ...
// now read the file
char data;
while (fread(&data, sizeof(char), 1, input) == 1) {
    // do something
}

Well, this worked finely but my teacher said I shouldn't read a file line by line because this would increase the amount of I/O. So now I need to read the whole binary file at a time. How can I do this? Could anyone help?

maxwellhertz
  • 343
  • 1
  • 5
  • 14
  • 7
    You're not reading line by line, you're reading character by character. Buffered I/O means it will be more efficient than you might expect. – Mark Ransom Sep 25 '18 at 00:50
  • 2
    Helpful reading: [Reading all bytes from a file (answer 1)](https://codereview.stackexchange.com/a/22907) Note you need a lot of RAM for a big file. – user4581301 Sep 25 '18 at 00:50
  • Oh... I'm a beginner with C++ so I'm confused about some concepts. @MarkRansom – maxwellhertz Sep 25 '18 at 00:56
  • Thanks! You really help me a lot!@user4581301 – maxwellhertz Sep 25 '18 at 01:14
  • 1
    Some additional detail: https://stackoverflow.com/questions/23312825/why-is-reading-blocks-of-data-faster-than-reading-byte-by-byte-in-file-i-o – Will Bickford Sep 25 '18 at 01:39
  • Possible duplicate https://stackoverflow.com/questions/51352863/what-is-the-idiomatic-c17-standard-approach-to-reading-binary-files – Galik Sep 25 '18 at 02:14

2 Answers2

1
unsigned long ReadFile(FILE *fp, unsigned char *Buffer, unsigned long BufferSize)
{
    return(fread(Buffer, 1, BufferSize, fp));
}

unsigned long CalculateFileSize(FILE *fp)
{
  unsigned long size;
  fseek (fp,0,SEEK_END);
  size= ftell (fp); 
  fseek (fp,0,SEEK_SET);
  if (size!=-1)
    {
      return size;
    }
  else
  return 0;
}

This function reads the file and stores it into a buffer, so accessing buffer reduce your IO time:

int main()
{
    FILE *fp = fopen("Path", "rb+");// i assume reading in binary mode
    unsigned long BufferSize = CalculateFileSize(fp);//Calculate total size of file
    unsigned char* Buffer = new unsigned char[BufferSize];// create the buffer of that size
    unsigned long  RetValue = ReadFile(fp, Buffer, BufferSize);
}
Muzol
  • 275
  • 1
  • 11
Roshan M
  • 133
  • 8
  • @user4581301 I have just Edit the solution. Can You please up vote? Thanks – Roshan M Sep 26 '18 at 10:49
  • Removed downvote. Upvote requires explanation, adherence to C++ idiom over C, and, since this question's been answered hundreds of times, something novel. – user4581301 Sep 26 '18 at 16:58
1

First notice that if you read the file to an 1 byte buffer (data variable in your code), your program will probably crash (if the filesize > 1). So, you need to allocate a buffer to read the file.

FILE *f = fopen(filepath, "rb+");
if (f)
{
    fseek(f, 0L, SEEK_END);
    long filesize = ftell(f); // get file size
    fseek(f, 0L ,SEEK_SET); //go back to the beginning
    char* buffer = new char[filesize]; // allocate the read buf
    fread(buffer, 1, filesize, f);
    fclose(f);

    // Do what you want with file data

    delete[] buffer;
}
Jorg B Jorge
  • 1,041
  • 9
  • 17
  • 1
    It would be better to use a `vector` instead of `char` array in this case. Also, [ftell returns a `long`, not an `int`](https://en.cppreference.com/w/cpp/io/c/ftell). – Paul Belanger Sep 25 '18 at 12:54