Sign in to follow this  
faculaganymede

istream::seekg -- Is there a max seek position limit?

Recommended Posts

C/C++ gurus, I am writing some code to read a very big binary image file (~2.4 GB). I use istream::seekg to set the file pointer to a desired position in the file and then read a floating point value: ----------------------------------------- unsigned long pos; //also tried this as long double ... fp.seekg(pos, ios::beg); cout << "File pointer is at " << fp.tellg() << endl; fp.read((char*)&value, sizeof(float)); ----------------------------------------- fp.seekg appears to work OK when pos is small. If pos is big, for example pos=2147487300, fp.tellg returns: "File pointer is at 2147477876". Clearly, it is wrong. The value read is also wrong. Is there a max value limit for pos, beyond which istream::seekg fails? I know the image file is OK because I can read the data in a commercial image viewer. Thanks.

Share this post


Link to post
Share on other sites
That is a little strange. I have used files larger than 2GB on Win32 with MSVC++ .NET 2005's standard library before.

Which compiler/system are you using?

Share this post


Link to post
Share on other sites
Don't do that. Seriously visual studio 6 is an utterly pathetic excuse for a compiler (it's 10+ years old - and was released before C++ was standardized). The express editions of visual studio are free - download Visual C++ Express 2008 - it's a MUCH MUCH better program.

Share this post


Link to post
Share on other sites
Quote:
Original post by cshowe
Don't do that. Seriously visual studio 6 is an utterly pathetic excuse for a compiler (it's 10+ years old - and was released before C++ was standardized). The express editions of visual studio are free - download Visual C++ Express 2008 - it's a MUCH MUCH better program.


Agreed. Visual C++ 6.0 is a poor compiler for C++ code. It doesn't come anywhere close to the standard in many respects, so it's better off not acknowledging it anymore.

Share this post


Link to post
Share on other sites
Quote:
Original post by faculaganymede
In case anyone is interested, the reason for the error is because pos should be "long" type, 32bit number on Windows.

That's odd. Shouldn't it be unsigned? If so, then it should be able to address a 4GB file.

Share this post


Link to post
Share on other sites
Quote:
Original post by cshowe
Don't do that. Seriously visual studio 6 is an utterly pathetic excuse for a compiler (it's 10+ years old - and was released before C++ was standardized). The express editions of visual studio are free - download Visual C++ Express 2008 - it's a MUCH MUCH better program.


Yeah, the only suggestions that I have as well would be to either:

a) Upgrade like cshowe suggests, or...
b) Use the Win32 API file-related functions. I think they have a file size limit of something ridiculously large like 2TB. These will work just fine with MSVC++ 6.0, but your code will no longer be strictly ISO C++ compliant.

By the way, if this is related to GIS -- you guys are all crazy with your 2GB image files!!!!! :)

Share this post


Link to post
Share on other sites
There is, technically: std::numeric_limits<X>::max, where X is one of std::streampos or std::streamoff depending on what kind of seeking you are doing.

Also, note those are typedefs provided by the standard library; to be pedantic, you should be using them. (For relative seeking - the 2-argument form of seekg - streamoff is appropriate, as it represents a stream [i]offset[/b]; for absolute seeking, you use streampos - stream position.)

Share this post


Link to post
Share on other sites
Thanks for all your feedbacks.

Quote:
Original post by Sc4Freak
That's odd. Shouldn't it be unsigned? If so, then it should be able to address a 4GB file.


Apparently, it's signed long because the error occurs when pos > 2^32/2.

p.s. The reason I am still using VS 6.0 is because I have to work with legacy code and don't have the time right now to port everything to a new compiler, unfortunately.

Share this post


Link to post
Share on other sites
Quote:
The reason I am still using VS 6.0 is because I have to work with legacy code and don't have the time right now to port everything to a new compiler, unfortunately


It is a signed long, and this doesn't change with later versions MVS, unless you're compiling 64-bit application, in which case it's a signed 64-bit int.

The reason for this lies in Windows, not the compiler itself. Microsoft's standard library maps most stdio operations to windows functions. In this case, to SetFilePointer.

In most cases, this isn't even remotely the problem. Not so long ago, 2 gig was a limit in Windows, or better yet, in FAT.

Anyone dealing with large files will use the *Ex versions of Windows API. It's not C++ anymore, but it gets the job done. I'm not sure on standard itself, but the long requirement might be part of standard as well, or it might be undefined.

Then again, C++ gives few portability guarantees.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this