6

Which is faster? ifstream or fread.
Which should I use to read binary files?

fread() puts the whole file into the memory.
So after fread, accessing the buffer it creates is fast.

Does ifstream::open() puts the whole file into the memory?
or does it access the hard disk every time we run ifstream::read()?

So... does ifstream::open() == fread()?
or (ifstream::open(); ifstream::read(file_length);) == fread()?

Or shall I use ifstream::rdbuf()->read()?

edit: My readFile() method now looks something like this:

void readFile()
{
    std::ifstream fin;
    fin.open("largefile.dat", ifstream::binary | ifstream::in);
    // in each of these small read methods, there are at least 1 fin.read()
    // call inside.
    readHeaderInfo(fin);
    readPreference(fin);
    readMainContent(fin);
    readVolumeData(fin);
    readTextureData(fin);
    fin.close();
}

Will the multiple fin.read() calls in the small methods slow down the program? Shall I only use 1 fin.read() in the main method and pass the buffer into the small methods? I guess I am going to write a small program to test.

Thanks!

Snowfish
  • 6,229
  • 4
  • 18
  • 20
  • 4
    What you should do is write two programs, one for each method, and see which is faster. Use a large file. – Björn Pollex May 25 '11 at 21:42
  • 1
    Some platforms have functions to treat a file as memory, either by reading the contents into memory or just accessing the file like memory. Search the web for "memory file". – Thomas Matthews May 25 '11 at 22:35
  • Worst case, multiple reads are slower than one larger read. The customary practice is to allocate a large buffer (in dynamic memory), read a large amount into the buffer, then parse the buffer. This performance should be measured since some OS and some disk drive manufacturers buffer large amounts of data anyway, to smooth future accesses. – Thomas Matthews May 25 '11 at 22:37

5 Answers5

5

Are you really sure about fread putting the whole file into memory? File access can be buffered, but I doubt that you really get the whole file put into memory. I think ifstream::read just uses fread under the hood in a more C++ conformant way (and is therefore the standard way of reading binary information from a file in C++). I doubt that there is a significant performance difference.

To use fread, the file has to be open. It doesn't take just a file and put it into memory at once. so ifstream::open == fopen and ifstream::read == fread.

Christian Rau
  • 43,206
  • 10
  • 106
  • 177
  • 1
    It will pull the whole file into memory if you tell it to, and if it can. And when it comes to I/O whether you doubt there is a performance difference or not is neither here nor there - the only thing to do is measure it. –  May 25 '11 at 21:50
  • @Neil How do you tell it to, query the file's size and read a block of the whole size? You can do that with `ifstream`, too. – Christian Rau May 25 '11 at 21:58
  • Yes you can do it with both? And so? –  May 25 '11 at 22:01
  • I think, the OP thought it just takes a file and puts it into memory at a whole. But that's just wrong, `fread` and `ifstream::read` serve the same functionality and your comment didn't really help to clarify that to him. – Christian Rau May 25 '11 at 22:07
  • How do you know "your comment didn't really help to clarify that to him"? –  May 25 '11 at 22:09
  • 3
    @Neil I'll hopefully end this discussion now. I just meant don't state half-truths. Of course an `fread` can read the whole file, but an `ifstream::read` can just do exactly the same. And I know you always can and should measure things, that's why I said "doubt" and not "know". – Christian Rau May 25 '11 at 22:17
  • Thanks! Now I understand that ifstream::read == fread. But then I figured out my true question from your answer, which is if I should ifstream::read once, and pass the buffer around, or ifstream::open, and pass the ifstream around to have multiple ifstream::read. – Snowfish May 25 '11 at 22:23
3

C++ stream api is usually a little bit slower then C file api if you use high level api, but it provides cleaner/safer api then C. If you want speed, consider using memory mapped files, though there is no portable way of doing this with standard library.

Nekuromento
  • 1,957
  • 1
  • 15
  • 16
3

As to which is faster, see my comment. For the rest:

  • Neither of these methods automatically reads the whole file into memory. They both read as much as you specify.
  • As least for ifstream I am sure that the IO is buffered, so there will not necessarily be a disk access for every read you make.
  • See this question for the C++-way of reading binary files.
Community
  • 1
  • 1
Björn Pollex
  • 70,106
  • 28
  • 177
  • 265
  • Thanks for the answer, I saw the question. The problem is the read() method was written by someone else. He ifstream::open() the file in the main read method, and pass the ifstream to small readContent() methods, which has fin.read() inside them. So I got confused if I should combine the fin.read() into 1 big fin.read() and pass the buffer to the small methods. – Snowfish May 25 '11 at 22:14
  • @Snowfish: I am not sure I understand. I think it would be best if you post this as a separate question and show the code you have. – Björn Pollex May 26 '11 at 07:59
0

The idea with C++ file streams is that some or all of the file is buffered in memory (based on what it thinks is optimal) and that you don't have to worry about it.

I would use ifstream::read() and just tell it how much you need.

Steve Blackwell
  • 5,809
  • 31
  • 48
  • Unfortunately, depending on "what it thinks is optimal" will not typically give you optimal performance. –  May 25 '11 at 21:54
-1

Use stream operator:

DWORD processPid = 0;
std::ifstream myfile ("C:/Temp/myprocess.pid", std::ios::binary);
if (myfile.is_open())
{
    myfile >> processPid;
    myfile.close();
    std::cout << "PID: " << processPid << std::endl;
}
zuko
  • 522
  • 1
  • 5
  • 15