Как записать данные в> 4 ГБ файл с C ++? - PullRequest
7 голосов
/ 21 августа 2011

Я пытаюсь написать большой файл, но столкнулся с проблемой.

Я использую long long для поиска места для записи, но не могу записать файл более 4,2 ГБ.Что я забыл?

Подробнее: я открываю 4Gb-файл:

ifstream ifs(db_name.c_str(), ios_base::binary);
if (!ifs) 
    throw Bad_archive();
ifs.read(as_bytes(seg_size), sizeof(int));
ifs.read(as_bytes(last_idx), sizeof(int));
ifs.read(as_bytes(free_segs), sizeof(int));
if (free_segs > 0)
{
    long long seek_g = 3 * sizeof(int) + (long long)last_idx * seg_size;
    ifs.seekg(seek_g, ios_base::beg);
    for (int i = 0; i < free_segs; i++)
    {
        int tmp = 0;
        ifs.read(as_bytes(tmp), sizeof(int));
        free_spaces.push_back(tmp);
    }
}
ifs.close();

После этого я читаю 400Mb-файл, который хочу добавить в БД.И напишите (вот краткий код):

// write object
ofstream ofs(db_name.c_str(), ios_base::binary | ios_base::in | ios_base::ate);
for (int i = 0; ; i++)
{
    // set stream position
    long long write_position = sizeof(int) * 3;

    ...

    write_position += (long long) seg_size * last_idx;
    ofs.seekp(write_position, ios::beg);

            ...

    // write sizeof object
    if (i == 0)
        ofs.write(as_bytes(object_size), sizeof(object_size)); 
    else
    {
        int null = 0;
        ofs.write(as_bytes(null), sizeof(null));
    }

    // write data
    for (int j = 0; j < (seg_size - sizeof(int) * 2); j++)
    {
        ofs.write(as_bytes(obj_content[j + i * (seg_size - sizeof(int) * 2)]), 
        sizeof(char));

    }
    if (write_new_seg)
        last_idx++;

    ...

    ofs.write(as_bytes(cont_seg), sizeof(cont_seg));
}
ofs.close();

После этого я сохраняю информацию в БД:

if (last_idx == 0)
{
    ofstream ofs(db_name.c_str());
    ofs.close();
}
ofstream ofs(db_name.c_str(), ios_base::binary | ios_base::in | 
            ios_base::out | ios_base::ate);
long long seek_p = 0;
ofs.seekp(seek_p, ios_base::beg);
ofs.write(as_bytes(seg_size), sizeof(seg_size));
ofs.write(as_bytes(last_idx), sizeof(last_idx));
ofs.write(as_bytes(free_segs), sizeof(free_segs));
ofs.close();

Но этот код работает:

ofstream ofs2("huge2");
ofs2.close();
ofstream ofs("huge2", ios_base::in | ios_base::ate);
long long sp = 10000000000;
ofs.seekp(10000000000, ios_base::beg);

ofs.write(as_bytes(sp), sizeof(sp));

ofs.close();

Ответы [ 4 ]

4 голосов
/ 26 августа 2011
    fseeko64 (Filename, 0, SEEK_END);
    long size = ftello64 (Filename);
    fclose (Filename);

Для доступа к большим файлам нельзя использовать fseek, вместо этого нужно перейти к fseeko64 ();

1 голос
/ 21 августа 2011

Есть функция _lseeki64 () в Win32 и lseek64 () в * nix. Библиотека iostream, однако, не оборачивает их напрямую, вам придется каким-то образом извлечь дескриптор файла и что-то сделать с буферизацией.

0 голосов
/ 26 августа 2011

Хорошая сводка для Linux здесь:

http://www.suse.de/~aj/linux_lfs.html

И, более конкретно, от RedHat, нацеленного на RHEL, эти проблемы обычно касаются 32-битных приложений, обращающихся к файлам размером 64-бит.

http://people.redhat.com/berrange/notes/largefile.html

В Википедии есть статья о Поддержка больших файлов , но не очень информативная.

0 голосов
/ 21 августа 2011

Многие файловые системы не поддерживают файлы размером более 4 ГБ. Кроме того, вы должны учитывать, что ваш тип int может иметь диапазон, который заканчивается на 2^32, то есть 4.29497e + 09.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...