1

I'm trying to read a large binary file but my code fails to open files larger than 4GB. Here's my code (I'm using Visual Studio 2012, compiling in x64):

#include "stdafx.h"
#include <fstream>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char* filename = "testfile";

    ifstream file (filename, ios::in|ios::binary|ios::ate);
    if (file.is_open())
    {
        cout << "file is open" << endl;
    }
    else
    {
        cout << "couldn't open file" << endl;
    }

    return 0;
}

As suggested in the comments I checked the output of GetLastError() with the following modification:

// ...
ifstream file (filename, ios::in|ios::binary|ios::ate);
DWORD lastError = GetLastError();
cout << lastError << endl;  // -> 87
// ...

Do you have any advice?

user2033412
  • 1,950
  • 2
  • 27
  • 47

2 Answers2

0

Can't comment yet, so this will do.

I'm guessing that Microsoft has implemented std:streamoff with sizeof(std:streamoff) == sizeof(int)

This means, when you try to ios::ate, the file's stream position val overflows, for files larger than 4GB (gibibytes). (I am doing a wild guess here)

This assumes your filesystem supports files larger than 4GB.

(Edit: thanks, I mistakenly put streampos instead of streamoff)

Viktor
  • 155
  • 8
  • `cout << "sizeof(streampos): " << sizeof(std::streampos) << endl;` gives me 24. – user2033412 Jul 30 '15 at 14:25
  • Better `sizeof(std::streamoff)` which is the actual type for offsets in streams. – lisyarus Jul 30 '15 at 14:29
  • `cout << "sizeof(streamoff): " << sizeof(std::streamoff) << endl;` gives me 8. – user2033412 Jul 30 '15 at 14:30
  • 1
    Since Visual C++ 2010, `std::streamoff` is 64-bit `long long` for all targets (prior to Visual C++ 2010, it was 32-bit `long` for 32-bit targets and 64-bit `long long` for 64-bit targets). – James McNellis Jul 30 '15 at 14:59
  • @user2033412 did you test a file exactly 4gb in length? Does a file larger, say by a byte work? Does it work if you get rid of ios::ate? – Viktor Jul 30 '15 at 15:15
0

I used to open the file with ios::ate because i wanted to get the filesize with the following code:

filesize = file.tellg();

As opening the file with ios::ate didn't work for files larger than 4GB I now open the file like this:

ifstream file (filename, ios::in|ios::binary);

without ios::ate and use

file.seekg(0, ios::end);
filesize = file.tellg();

to get the filesize.

user2033412
  • 1,950
  • 2
  • 27
  • 47