seekg and file of 4294967295 bytes

I'm using VS2010, and I found very weird thing.

If you're working with the file of exact size of 4294967295 bytes, seekg fails!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <fstream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    std::ifstream file;

    // cmd: fsutil file createnew tmp.txt 4294967295
    file.open(L"c:/tmp.txt", ifstream::in | ifstream::binary);

    if(!file.is_open())
        return -1;

    file.seekg(0, std::ios::end);

    auto state = file.rdstate();

    // this condition shoots only when size of the file is equal to 4294967295
    if((state & ifstream::failbit)==ifstream::failbit)
    {
        std::cout << "seekg failed";
    }

    // after seekg failed, tellg returns 0
    std::streampos endPos = file.tellg();

    return 0;
}


Same code with files of 4294967294 and 4294967296 is working without any problems.

Does someone know a solution to this problem?
That's because you're working on a 32bit system where -1 happens to be a legitimate file size for your system. I expect that you'll have other problems as you can't seek beyond that size too. It's the classic memory model problem.

You can specify the memory model for STL objects (for lack of a better word), but the IOStream library isn't part of STL, so to my knowledge, you can't use it. Now that'd be a useful feature in a new version of the standard library (rather than the crap that's in it now).

You may already know that the WIN32 file functions have always been 64bit (to support the 64 bit filesystem). So you may have to resort to using them directly.
Last edited on
It has nothing to do with 32bits system (btw I'm using windows 64 bit)

In my first post I specifically mentioned that it's working fine with 4294967296 file.
It has nothing to do with 32bits system


Then it seems a truly spectacular coincidence. Your post of the same over on stackoverflow seems to have the answer. Someone chose to use the max value of a 32 bit int as the error code.

If I had to guess, the code was originally written for 32bit systems, safe in the knowledge that nobody would ever seek this value as such a file size was impossible. So it does have a lot to do with 32 bit systems.
Last edited on
The answer on stackoverflow is incorrect

The problem lies exactly in this snip of code
1
2
3
4
5
6
7
8
template<class _Statetype>
class fpos
{
 __CLR_OR_THIS_CALL operator streamoff() const
 { // return offset
 return ((streamoff)(_Myoff + _FPOSOFF(_Fpos)));
 }
}


where
 
#define _FPOSOFF(fp) ((long)(fp)) 


While all types(_Myoff, _Fpos) are 64 bit, so this reckless conversion to long creates a problem.
Last edited on
Topic archived. No new replies allowed.