![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Работаю с большим файлом ~30Gb, использую fstream
В Dev-C++ все в порядке, VC затыкается на ~2Gb. Ошибку найти не могу, вроде в seek везде использую long long. В любом случае код тот же. Может такое быть, что fstream из VC не работает большими файлами? Или есть неочевидные особенности? Как вообще найти такого рода ошибку? |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
да, в свойствах fstream для размера и т.п. используется int.
поищи в гугле traits для fstream, думаю, там будут советы, как поменять int на long long (кажись, это не просто) |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Да, действительно int.
Советов не нашел. А почему в DevC++ работает как надо? И как в VC работают с большими файлами? |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
нда, там кода куча для работы с большими файлами
http://www.cyberguru.ru/programming/cpp/cp...aits-page4.html Это сообщение отредактировал(а) Alek86 - 7.12.2007, 16:50 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
tatan, по стандарту позиция файла должна указываться типом streampos. У gcc это typedef fpos<mbstate_t> streampos;
шаблон fpos, содержит поле streamoff _M_off; а streamoff - это typedef от long long или int64 |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
нда, сложновато для меня-новичка
спасибо |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Не хочешь наступить на грабли MS? Тогда вместо long long используй streampos для установки/хранения позиции файла. |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
На грабли не хочу ни MS, ни любые другие, но так видимо устроен мир
Спасибо, вечером буду пробовать streampos |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
tatan, на граблях учатся лучше всего. Ты уже на одни наступил, а о следующих я предупредил...
|
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Видимо я что-то не понял
Приведение типов в стиле С (streampos) во всех seek'ах и вообще во всех нужных и ненужных местах ничего не изменило VC++, видимо лучший компайлер, но бороться не буду - потренируюсь с gss Все же что-то не так делаю, bsa, вы могли могли бы уточнить свои рекомендации для чайников? |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
tatan, обнови VS на что-то более новое. Скорее всего, у тебя какая-то древняя версия.
|
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Неа, MS Visual Studio 2008
Version 9.0.21022.8 RTM |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
странно.
|
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
to bsa: могу ли я вам сбросить код на mail? для проф комент
Чертовски был бы благодарен за помощь вам будет интересно, но сюда неприлично- слишком сыро а если вы в мск - проставлюсь по-любе smile |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Да тут довольно просто все.
Дело в том, что ofstream::pos_type содержит streamoff, который действительно небольшой в VC, и fpos_t, который достаточного размера. Соответственно есть разные конструкторы для его инициализации. fstream::seekp() тоже имеет две формы - с pos_type и off_type в качастве типа параметра. Посмотрите код ниже, как это делается. Компилилось на VS 2003. Размер файла в примере 2.5Г т.к. на диске просто больше нет места
|
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
baldina
tnx, но не сейчас сейчас уже время для виски |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
baldina, gss ругается на строку
ofstream::pos_type size (0, filesize); говорит 'no matching function for call to `std::fpos<mbstate_t>::fpos(int, long long int&)' и на строку cout << "File size is " << size.seekpos ()/(1024.*1024*1024) << "Gb\n"; 'class std::streampos' has no member named 'seekpos' |
|||
|
||||
| baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
По стандарту класс fpos is implementation-defined. И реализация в VC и gcc как видно различается.
Значит не удастся единообразно сделать. Увы. Видимо имеет смысл обернуть работу с fpos в класс, реализация которого разная для разных типов компиляторов. Добавлено через 11 минут и 5 секунд Т.е. предлагается создать класс примерно такого вида (реализация для gcc и VC будет разная)
тогда те проблемные строчки могут выглядеть так:
|
||||
|
|||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Пока знаний маловато
Вообщем пока сделал так
Не знаю, насколько такой подход правильный |
|||
|
||||
| baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Нормальный подход.
А мое предложение заключалось в том, что если таких мест много, не плодить дефайны по коду, а собрать только в одном месте. Связность системы надо уменьшать. Т.е.
тогда можно писать
|
||||
|
|||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
спасибо
завтра попробую |
|||
|
||||
| hkklr |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 17.8.2007 Репутация: нет Всего: нет |
Если вы про Visual Studio, то там вобще в стандартной библиотеке всё криво написано. Да и вообще, зачем нужны эти объектно-ориентированные потоки, тормозные они...
|
|||
|
||||
| archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
hkklr, конечно, давайте лучше вернёмся в каменный век, ради выйгрыша в пару тактов.
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
К сожалению, даже благодаря любезному baldina заставить работать VC с большим файлом не удалось, наверное я что-то недопонял
Если кому-то будет интересно выкладываю небольшие исходники. gcc с этим работает правильно работает вот блин Присоединённый файл ( Кол-во скачиваний: 7 )
adb.zip 13,64 Kb |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Про криво сами додумались али кто подсказал? Не поленитесь, посмотрите копирайты включаемых файлов. Заодно интересно было б услышать, что именно там криво. Sorry за |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Запускаю исходники, получаю такой результат:
Это верно или как? Файло указанного размера создалося... Компилятор - VC 2003 Добавлено через 12 минут и 12 секунд Глядя внутрь исходников, делаю осторожный вывод, что по крайней мере в отношении pos_type все правильно. |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
У меня MS VS 9
выдает File size: 0 Сам файл 4096 Mb а должен быть - миллион страниц по 8192Kb Dev-C++ с gсс говорит все правильно - 7813Mb К тому же в main есть вызов, проверяющий логику программы - f.SetPageFree(999997), здесь он отрабатывает правильно - помечает в файле страницу с таким порядковым номером свободной Непонятно, почему у нас разные результаты прогонов с VC Добавлено через 3 минуты и 2 секунды "Глядя внутрь исходников, делаю осторожный вывод, что по крайней мере в отношении pos_type все правильно. " Ну значит Ваше время потрачено не зря Собственно я без изменений Ваш код и засунул Может правда использовал его не так, я там с бубном прыгал в простом файле adbfile.cpp |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Ну у меня 7гиг свободных просто нету, чуть больше 3х сейчас. И файл создался примерно такой.
MS VS 9 - Это что, 2008? Здесь нету, а завтра на работе могу и под него попробовать. И вряд ли оно стухло в более поздней. Стоит поглядеть, действительно ли под VC компилируется то что надо. Отладчик для того придумали. Может, конечно, моё заклинание только на моём компе работает Добавлено @ 01:46 Ваш бубен видел, вы там еще забыли return в случае если файл не открыт... Добавлено @ 01:48 В утешение: поглядите в boost, как они бьют в бубен для каждого компилятора (и даже версии) Это сообщение отредактировал(а) baldina - 10.12.2007, 01:48 |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Да, MS Visual C++ 2008 Express Edition
До 4Gb работает нормально и в VC, можно убедиться поставив в for место 1000000 400000, и поменяв в f.SetPageFreу аргумент на например 399997 boost ни разу не видел, рановато думаю еще, но утешаюсь Если не очень трудно, попробуйте plz про return наверное не забыл я буду думать еще про систему обработки ошибок и исключений, пока просто не обращаю внимания |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Ладно, утром поглядим
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
tatan, а у тебя файловая система на диске случайно не FAT?
|
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Нет, конечно
Я же говорю, gcc нормально работает |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Вобщем так. VC 7.1 и VC 9 работают одинаково. Файл у меня создается немногим больше 4Г (т.е. 4Г - не ограничение).
Затыкается, когда вот тут
k становится равным 0. Посмотрел как записывается ADBPageDescriptor, но так и не понял. Во многих местах похожий, но разный код, разбираться лень. Но дело тут явно не в ограничениях на размер и не работе streamoff. Похоже где то либо переполнение (например в unsigned short), либо ошибка в приведении типа. Еще замечено, что поток вывода в некоторый момент приобретает ошибочное состояние, которое не анализируется и не сбрасывается сразу. Добавлено через 3 минуты и 41 секунду Я его долго мотал по отладчику (в т.ч. пытаясь понять, что оно таки делает Затыкается, когда pNum становится равным 65. |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Это файл, организованный из страниц одинакового размера, заготовка под будущую карманную СУБД
Есть системный тип страниц, SpaceInventoryPage, эти страницы содержат сведения о других страницах - свободны или нет. При открытии файла свободные страницы заносятся в вектор SIParray, для ускорения получения free page. Такие страницы организованы в список - у каждой в заголовке содержится номер предыдущей и следующей страницы ADBFile - просто файл и основные действия ADBPage - только для того, чтобы работать с зашифрованным RC-4 файлом, ADBPagedFile смотрит, если файл зашифрован, то подает клиенту расштфрованный буфер страницы. Можно было всю работу в ADBPageedFile организовать через ADBPage, но накладно. ADBPagedFile - собственно сам страничный файл, отвечает за выделение-освобождение, использование страниц Спасибо, baldina, буду искать косяк. Отладчиком пользоваться не умею, буду учиться. Правда, непонятно, почему с gcc работает и вроде как после интенсивной проверки логики |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
Короче, пока завязал с VC, следующий код, компиленный gcc, правильно работает, VC - нет
Видимо какие-то особенности VC я не принимаю о внимание Найду все равно Всем спасибо Програма создает файл ~6250 Mb, устанавливает файловый указатель на filesize - 100 и пишет в файл тестовую строку
|
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
tatan, дело оказалось не в программе.
Не работает fstream::seekp() на файлах больше 4Г. Потоки вызывают стандартную библиотеку С, та - ядреную функцию Win32. fstream::seekp() -> fseek() -> _lseek() -> SetFilePointer(). Вот SetFilePointer() (kernel32.dll) и не работает на больших файлах, если вызывается так, как это делает _lseek(). DWORD SetFilePointer( HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod ); lpDistanceToMoveHigh - NULL для небольших смещений, либо указатель на старшую часть смещения для больших. Так вот _lseek передает NULL. При таком вызове на больших файлах SetFilePointer завершается с ошибкой. А правильно вызывает 64-битная версия _lseek. Обойти можно так - я переделал стандартную функцию fseek(), вызвав её 64-битную версию. Надо просто добавить прилагаемый файл в проект, и будет работать. С CRT линковать надо статически. Удачи. Это сообщение отредактировал(а) baldina - 11.12.2007, 15:31 Присоединённый файл ( Кол-во скачиваний: 15 )
fseek_64.c 0,22 Kb |
|||
|
||||
| tatan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 70 Регистрация: 31.10.2007 Репутация: нет Всего: 1 |
A я стер ADBFile и переписал с FILE*,
и все заработало. спасибо, baldina, что столько времени потратил на меня, я попробую вернуться к fstream |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |