Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Создание больших файлов/изменение размеров файлов
Форум на CrossPlatform.RU > Библиотеки > Другие библиотеки
wiz29
Всем привет. Интересует вопрос создания больших в файлов под linux/unix/mac os (PC) под виндой решение мне известно в т.ч. средставами QFile получается сделать быстро:

платформозависимое решение windows
    HANDLE hfile = ::CreateFileA(fileName.toAscii().data(), GENERIC_WRITE,
                                              0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                                              NULL);
    if (!hfile)
    {//general way
        ExtendsCommon(fileName, fileSize);//функция реализующая изменение размера с заполнением файла данными
        return;
    }
    LARGE_INTEGER size;
    size.QuadPart = fileSize;
    SetFilePointer(hfile, size.LowPart, &size.HighPart, FILE_BEGIN);
    SetEndOfFile(hfile);
    CloseHandle(hfile);


с помощью QFile работает так же быстро:
    QFile file;
    file.setFileName(fileName);
    file.open(QFile::Truncate | QFile::ReadWrite);
    file.resize(fileSize);
    file.close();


для примера размер переменной в моих тестах == 6.5 Gb
Виндовый код отрабатывает с точки зрения пользователя мгновенно (конкретное время не замерял). Под linux\unix\mac os (с случае реализации через QFile) наблюдается подвисание в момент вызова file.close(). При стандартной работе через стандартные C функции результат с тормозами такой же на закрытии файла close(fd).
    int fd = open(file.toStdString().c_str(), O_TRUNC | O_CREAT | O_RDWR);
    off_t res = ftruncate(fd, fileSize);
    Q_ASSERT(res != -1);
    close(fd);//тут происходит подвисание (под виндами не происходит в аналогичном участке кода)


Если кто то знает как можно справится с проблемой просьба подсказать. Заранее всем спасибо.
Iron Bug
линюкс заполняет всё неинициализированное пространство нулями. венда оставляет там мусор. потому и быстрее.
но я не знаю, есть ли под линюксом функции расширения размера файла с оставлением в файле мусора.

вообще, это зависит от файловой системы: есть понятие sparse file, и такой формат поддерживают не все файловые системы.
у меня 64-битный линь на Ext4 вот такой код выполняет моментально:

    int fd = open("somefile.bin", O_WRONLY|O_TRUNC|O_CREAT, 0600);
    cout << "Opened" << endl;
    write(fd, "start", 5);
    lseek(fd, 6500000000, SEEK_CUR);
    write(fd, "end", 3);
    close(fd);
    cout << "Closed" << endl;


в результате - 6.5 с хвостиком гигов на винте. середина заполнена нулями. но на самом деле это sparse file и ось реально там какие-то свои методы юзает для обозначения нулей при хранении.

P.S. кстати, и приведённый в вопросе код (с ftruncate) у меня отрабатывает за доли секунды. машина далеко не монстр. просто файловая система правильная.
wiz29
с линукс вопрос решен, спасибо за подробный комментарий. Осталось странное поведение под mac os. Видимо что то с поддержкой sparce files на mac os 10.6.8 все-таки работает криво. Код с ftruncate работает с тормозами (при этом создается реально файл равный заданному размеру). Зато работает без нареканий код:
    int fd = open(fileName.toStdString().c_str(), O_CREAT | O_APPEND | WRONLY | O_NONBLOCK);
    if (!fd)
    {
         return;
    }
    off_t res = lseek(fd, fileSize, SEEK_CUR);
    Q_ASSERT(res == fileSize);
    char eof = -1;
    res = write(fd, &eof, sizeof(eof));
    Q_ASSERT(res == sizeof(eof));
    close(fd);


Но при этом размер файла изначально равен размеру кластера 4Кб, затем при его эксплуатации размер увеличивается. Нормально ли это? (ведь в виндах и никсах ос показывает размер файла сразу корректно)
Iron Bug
Цитата(wiz29 @ 22.5.2012, 12:52) *
размер файла изначально равен размеру кластера 4Кб, затем при его эксплуатации размер увеличивается. Нормально ли это?

скорее всего, это реализация конкретной файловой системы. я с макосью дел практически не имею, так что наверняка сказать не могу. могу предложить вот это:
http://stackoverflow.com/questions/186077/...n-c-on-mac-os-x
там народ что-то пишет про sparse files под макосью.
wiz29
Да, у меня HFS файловая система, она таких файловых операций не поддерживает.

А так реализация QFile::resize кроссплатформенно, по сути, закрывает этот вопрос полностью.
Iron Bug
Цитата(wiz29 @ 22.5.2012, 14:56) *
закрывает этот вопрос полностью.

да, но скорость работы функции всё равно будет зависеть от файловой системы. от этого никуда не денешься.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.