Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can ifstream read file more than 2G?

10 views
Skip to first unread message

Water Lin

unread,
Jun 5, 2009, 2:36:00 AM6/5/09
to
I am using ifstream to read file. But when I read a file about 2.8G, the
ifstream will return a size like these:
------------------
-1358985216
------------------

Here is my code:
-----------------------
string dir = "C:\\test";
uint64 size;
ifstream infile(dir.c_str(), ios::in | ios::binary | ios::ate);
if ( infile.is_open() )
{

size = infile.tellg();
}
---------------------

Why the size will be a negative?

Anything wrong?

Someone told me that I should use a 64bit edition of ifstream, is it
true?

--
Water Lin
http://blog.waterlin.org

Alf P. Steinbach

unread,
Jun 5, 2009, 3:07:13 AM6/5/09
to
* Water Lin:

> I am using ifstream to read file. But when I read a file about 2.8G, the
> ifstream will return a size like these:
> ------------------
> -1358985216
> ------------------
>
> Here is my code:
> -----------------------
> string dir = "C:\\test";
> uint64 size;
> ifstream infile(dir.c_str(), ios::in | ios::binary | ios::ate);
> if ( infile.is_open() )
> {
>
> size = infile.tellg();
> }
> ---------------------
>
> Why the size will be a negative?

Assuming 'uint64' is an unsigned integer type, it can't be negative.


> Anything wrong?

See above.

'tellg' returns a 'pos_type'. By �27.1.2 'pos_type' is by default a 'streampos'
for iostreams. By �21.1.3.1/2 a 'streampos' satisifies the requirements for a
'POS_T' in �21.1.2. That paragraph explains that the requirements are described
in �27.1.2. And then we're full circle, recursive without a base case.

Amazingly, this is noted in �27.2/2, "This synopsis suggests a circularity
between streampos and char_traits<char>."

So at least, while not particularly useful for this issue, and while the
standard goes the extreme lengths to obscure the issue (three layers of
indirection, at the least), the standard is at least truthful.

I'm guessing wildly that someone who doesn't have my strong aversion to
iostreams, I mean, they're just *expletive deleted*, may contribute some tidbit
like e.g. something stated in the C standard, or original intent, or something.


> Someone told me that I should use a 64bit edition of ifstream, is it
> true?

For files larger than 2^31 bytes that does seem like a good idea, yes.

Or even better, define your own file handling. :-)


Cheers & hth.,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!

Message has been deleted

Bo Persson

unread,
Jun 5, 2009, 12:30:43 PM6/5/09
to

It it highly likely that ifstream can read files up to the size
supported by the OS.

On the other hand, tellg is limited by size of long - the largest
integer type in standard C++. What happens when the size or position
is larger than LONG_MAX? I think you just found that out.


Bo Persson


Paavo Helde

unread,
Jun 6, 2009, 12:33:14 AM6/6/09
to
Water Lin <Wate...@ymail.com> kirjutas:

> I am using ifstream to read file. But when I read a file about 2.8G, the
> ifstream will return a size like these:
> ------------------
> -1358985216
> ------------------

For files over 2G there may appear multiple problems, on multiple
platforms. One can use system-specific ways to work around them. For
example, in Windows there are a couple of functions for file size
(GetFileSizeEx() and _filelengthi64()) which are able to return a 64-bit
value. On Linux one might have to use things like _LARGEFILE64_SOURCE and
O_LARGEFILE.

Some problems may go away when switching to 64-bit compilation, some might
not. In any case, one ought to be able to work with large files also in a
32-bit program. If the C++ standard streams are not up to this task, one
has to use something else.

Paavo

James Kanze

unread,
Jun 7, 2009, 12:29:55 PM6/7/09
to
On Jun 5, 12:18 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
> Water Lin <Water...@ymail.com> writes:
> >ios::ate(...)tellg()(...)Anything wrong?

> »::std::ate« requests a seek to the end of the file.
> »seekg« and »tellg« seem to be defined using »pubseekoff« in
> ISO/IEC 14882:1998(E), which is defined in terms of »seekoff«,
> which is defined based on »::std::fseek«. ISO/IEC 9899:1990
> explains about »::std::fseek«:

> »A binary stream need not meaningfully support
> fseek calls with a whence value of SEEK_END.«

> Therefore, one can not assume that one will be able to obtain
> the size of a binary file in this way under every
> implementation of C++. One needs to look up the documentation
> of the implementation to find out whether it supports fseek
> calls with a whence value of SEEK_END.

> If this is not supported or if the result type of tellg()
> is too small, one solution is to read every byte from the
> file counting. However, when the result is kept for later
> use, one also needs to consider the possibility that the
> size of the file might change in the meantime.

That's really the only solution anyway. The function tellg
returns a streampos, which isn't even necessarily convertable to
an integral type, and even if it is convertable, the value of
resulting integer doesn't necessarily mean much; it can be some
sort of magic cookie.

In practice, there is no C++ way to determine the size of a
file, because:

1. "size of a file" can mean different things: how much space
the file occupies on the disk or how many bytes you can read
before you encounter end of file are the most obvious
meanings, and

2. many systems don't have an means of determining this
information.

In the end, you have to decide what you really want to know, and
then use some system specific means of obtaining the
information, provided that such a means exists.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

0 new messages