Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с большим файлом, fstream 
V
    Опции темы
bsa
Дата 10.12.2007, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



tatan, а у тебя файловая система на диске случайно не FAT?
PM   Вверх
tatan
Дата 10.12.2007, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



Нет, конечно
Я же говорю, gcc нормально работает
PM MAIL   Вверх
baldina
Дата 10.12.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Вобщем так. VC 7.1 и VC 9 работают одинаково. Файл у меня создается немногим больше 4Г (т.е. 4Г - не ограничение).
Затыкается, когда вот тут


Код

    double f = ceil( (double)pageNo / (double)(itsFileHeader.PageSize - sizeof(ADBPageDescriptor) ) ) ;
    unsigned long pNum = static_cast <unsigned long> (f);

    unsigned long k = itsFileHeader.FirstSIP;
    unsigned long j = 1;
    ADBPageDescriptor ph;
    memset((char*) &ph, 0, sizeof(ph));
    ph.ID = 1;
    ClearIO();
    while (j < pNum + 1)
    {
        //itsFile.seekg( (std::streampos) ((std::streampos)(k - 1) * (std::streampos)itsFileHeader.PageSize), std::ios::beg);
        //itsFile.read((char*) &ph, sizeof(ph));
        SetPosition((unsigned long long)(k - 1) * itsFileHeader.PageSize);
        ReadBuffer((char*) &ph, sizeof(ph));
        ClearIO();
        
       k = ph.NextPage; // <<<<<------- ВОТ ТУТ
       j++;
    };
    //itsFile.clear();



k становится равным 0.
Посмотрел как записывается ADBPageDescriptor, но так и не понял. Во многих местах похожий, но разный код, разбираться лень. Но дело тут явно не в ограничениях на размер и не работе streamoff. Похоже где то либо переполнение (например в unsigned short), либо ошибка в приведении типа.
Еще замечено, что поток вывода в некоторый момент приобретает ошибочное состояние, которое не анализируется и не сбрасывается сразу.

Добавлено через 3 минуты и 41 секунду
Я его долго мотал по отладчику (в т.ч. пытаясь понять, что оно таки делает  smile).
Затыкается, когда pNum становится равным 65.
PM MAIL   Вверх
tatan
Дата 10.12.2007, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



Это файл, организованный из страниц одинакового размера, заготовка под будущую карманную СУБД
Есть системный тип страниц, SpaceInventoryPage, эти страницы содержат сведения о других страницах - свободны или нет.
При открытии файла свободные страницы заносятся в вектор SIParray, для ускорения получения free page. 
Такие страницы организованы в список - у каждой в заголовке содержится номер предыдущей и следующей страницы
ADBFile - просто файл и основные действия
ADBPage - только для того, чтобы работать с зашифрованным RC-4 файлом, ADBPagedFile смотрит, если файл зашифрован, то подает клиенту расштфрованный буфер страницы. Можно было всю работу в ADBPageedFile организовать через ADBPage, но накладно.
ADBPagedFile - собственно сам страничный файл, отвечает за выделение-освобождение, использование страниц
Спасибо, baldina, буду искать косяк.
Отладчиком пользоваться не умею, буду учиться.
Правда, непонятно, почему с gcc работает и вроде как после интенсивной проверки логики
PM MAIL   Вверх
tatan
Дата 10.12.2007, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



Короче, пока завязал с VC, следующий код, компиленный gcc, правильно работает, VC - нет
Видимо какие-то особенности VC я не принимаю о внимание
Найду все равноsmile
Всем спасибо
Програма создает файл ~6250 Mb, устанавливает файловый указатель на filesize - 100 и пишет в файл тестовую строку
Код

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


#include "adbfile.hpp"
#include "adbcomm.hpp"
#include "adbpfile.hpp"

int main(int argc, char *argv[])
{
    ADBFile f("1.dat");
    f.CreateFile();
    f.OpenFile();

    const char* ch = "Test string for ADBFile";
        const int BUFSIZE = 8192 * 100;
    char* buf = new char [BUFSIZE];
    memset(buf, 0, BUFSIZE);
    const long pc = 8000;
    for (int i = 0; i < pc; i++)
    {
        f.SetPosition((unsigned long long)i * BUFSIZE);
        f.WriteBuffer(buf, BUFSIZE);
    }

    std::cout << "FileSize: " << f.Size() << std::endl;

    f.SetPosition(f.Size() - 100);

    std::cout << "Pos: " << f.GetPosition() << std::endl;
    f.WriteBuffer((char*) ch, strlen(ch));
    f.CloseFile();

    delete [] buf;
    system("PAUSE");
    return 0;
}


PM MAIL   Вверх
baldina
Дата 11.12.2007, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 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
PM MAIL   Вверх
tatan
Дата 11.12.2007, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



A я стер ADBFile и переписал с FILE*, 
Код

#ifdef _MSC_VER
    #define fopen64 fopen
    #define fseek64 _fseeki64
    #define ftell64 _ftelli64
#else
    #define fopen64 fopen64
    #define fseek64 fseeko64
    #define ftell64 ftello64
#endif    


 и все заработало.

спасибо, baldina, что столько времени потратил на меня, я попробую вернуться к fstream

PM MAIL   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0507 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.