ifstream, seekg, tellg и 2 GB+
От: CL0NE Украина  
Дата: 06.09.10 18:02
Оценка:
Суть проблемы:
      ifstream infile(strFilePath,ios::binary);
      infile.seekg(0,ios::end);
      long nSize = infile.tellg();
Приведенный код позволит нам узнать размер файла не более 2 ГБ. Нужно читать файлы любого размера (поддерживаемого FS, разумеется) и решение должно быть кроссплатформенным и не выходить за рамки стандартной библиотеки.

Мой путь:
Некоторое гугление и через некоторое время натыкаюсь на статью о traits на форуме sources.ru. Внимательное чтение, щенячий восторг и немедленное желание все воспроизвести. Однако результат не соответствует ожиданиям: все те же -825327616, что и без использования long_pointer_traits. Самое худшее, что даже и не знаю где печь, от которой плясать, чтоб разобраться с проблемой. Поэтому с удовольствием выслушаю все советы и отвечу на необходимые вопросы.

Использовался minGW из комплекта QtSDK (пожалуйста, не предлагайте использовать в качестве решения проблемы Qt) и файл размером в 3ГБ.
ifstream seekg tellg 2 gb
Re: ifstream, seekg, tellg и 2 GB+
От: Sni4ok  
Дата: 06.09.10 18:19
Оценка:
Здравствуйте, CL0NE, Вы писали:

CLN>Приведенный код позволит нам узнать размер файла не более 2 ГБ.


вы ошибаетесь, зависит от платформы, под 64х битным линуксом или 64х битной виндой- вернёт правильный размер, чтобы работало под 32х битной виндой, можно извратитсо:

inline boost::uint64_t GetFileSize(std::ifstream& ff){
    ff.seekg(0, std::ios::end);
    boost::uint64_t ret = ff.tellg()
#ifdef WIN32
        .seekpos()
#endif
    ;
    ff.seekg(0, std::ios::beg);
    return ret;
}


а вообще boost::filesystem::file_size -- возвращает корректный размер независимо от платформы, а если у вас не стримы, а сишные хендлы, то под 32 битной виндой можно пользоваться 64х битными версиями функций(_lseeki64, _fstat64 и т.п), а под 32х битным линуксом задефайнить макросы:
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
Re[2]: ifstream, seekg, tellg и 2 GB+
От: CL0NE Украина  
Дата: 07.09.10 12:44
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>Здравствуйте, CL0NE, Вы писали:


CLN>>Приведенный код позволит нам узнать размер файла не более 2 ГБ.


S>вы ошибаетесь, зависит от платформы, под 64х битным линуксом или 64х битной виндой- вернёт правильный размер, чтобы работало под 32х битной виндой, можно извратитсо:


S>
S>inline boost::uint64_t GetFileSize(std::ifstream& ff){
S>    ff.seekg(0, std::ios::end);
S>    boost::uint64_t ret = ff.tellg()
S>#ifdef WIN32
S>        .seekpos()
S>#endif
S>    ;
S>    ff.seekg(0, std::ios::beg);
S>    return ret;
S>}
S>



'class std::streampos' has no member named 'seekpos'



S>а вообще boost::filesystem::file_size -- возвращает корректный размер независимо от платформы, а если у вас не стримы, а сишные хендлы, то под 32 битной виндой можно пользоваться 64х битными версиями функций(_lseeki64, _fstat64 и т.п), а под 32х битным линуксом задефайнить макросы:

S>-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE

А без boost'а? на плюсовых стримах это сделать
Re[3]: ifstream, seekg, tellg и 2 GB+
От: Viper_Craft  
Дата: 07.09.10 13:02
Оценка:
Здравствуйте, CL0NE, Вы писали:

CLN>Здравствуйте, Sni4ok, Вы писали:


CLN>А без boost'а? на плюсовых стримах это сделать


а в ман заглянуть ни как?
streampos tellg ( );


std::streampos = <platform dependent type>
Re: ifstream, seekg, tellg и 2 GB+
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 07.09.10 13:08
Оценка: 3 (1)
Здравствуйте, CL0NE, Вы писали:

CLN>Суть проблемы:

CLN>
CLN>      ifstream infile(strFilePath,ios::binary);
CLN>      infile.seekg(0,ios::end);
CLN>      long nSize = infile.tellg();
CLN>
Приведенный код позволит нам узнать размер файла не более 2 ГБ. Нужно читать файлы любого размера (поддерживаемого FS, разумеется) и решение должно быть кроссплатформенным и не выходить за рамки стандартной библиотеки.


Смотри в сторону stat точнее тебе нужно _stat64
Re[4]: ifstream, seekg, tellg и 2 GB+
От: CL0NE Украина  
Дата: 07.09.10 13:22
Оценка: -1
Здравствуйте, Viper_Craft, Вы писали:

V_C>Здравствуйте, CL0NE, Вы писали:


CLN>>Здравствуйте, Sni4ok, Вы писали:


CLN>>А без boost'а? на плюсовых стримах это сделать


V_C>а в ман заглянуть ни как?

V_C>
V_C>streampos tellg ( );
V_C>


V_C>std::streampos = <platform dependent type>


ога, знаем-с, а как его заставить жрать int64 на x86, вот в чем соль
и статью про traits читали, да вот незадача, не работает.
Re[2]: ifstream, seekg, tellg и 2 GB+
От: CL0NE Украина  
Дата: 07.09.10 16:03
Оценка:
Здравствуйте, dabeat_bf, Вы писали:
_>Смотри в сторону stat точнее тебе нужно _stat64
спасибо наверное, пока не найду вариант со стримами, ею и буду пользоваться.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.