crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Тема закрытаНачать новую тему
> Создание больших файлов/изменение размеров файлов
wiz29
  опции профиля:
сообщение 21.5.2012, 13:22
Сообщение #1


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Всем привет. Интересует вопрос создания больших в файлов под 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);//тут происходит подвисание (под виндами не происходит в аналогичном участке кода)


Если кто то знает как можно справится с проблемой просьба подсказать. Заранее всем спасибо.

Сообщение отредактировал wiz29 - 21.5.2012, 13:34
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 21.5.2012, 20:20
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


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

вообще, это зависит от файловой системы: есть понятие 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) у меня отрабатывает за доли секунды. машина далеко не монстр. просто файловая система правильная.

Сообщение отредактировал Iron Bug - 21.5.2012, 20:28
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 22.5.2012, 9:52
Сообщение #3


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


с линукс вопрос решен, спасибо за подробный комментарий. Осталось странное поведение под 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Кб, затем при его эксплуатации размер увеличивается. Нормально ли это? (ведь в виндах и никсах ос показывает размер файла сразу корректно)

Сообщение отредактировал wiz29 - 22.5.2012, 9:54
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.5.2012, 11:47
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


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

скорее всего, это реализация конкретной файловой системы. я с макосью дел практически не имею, так что наверняка сказать не могу. могу предложить вот это:
http://stackoverflow.com/questions/186077/...n-c-on-mac-os-x
там народ что-то пишет про sparse files под макосью.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 22.5.2012, 11:56
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Да, у меня HFS файловая система, она таких файловых операций не поддерживает.

А так реализация QFile::resize кроссплатформенно, по сути, закрывает этот вопрос полностью.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.5.2012, 13:36
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(wiz29 @ 22.5.2012, 14:56) *
закрывает этот вопрос полностью.

да, но скорость работы функции всё равно будет зависеть от файловой системы. от этого никуда не денешься.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Тема закрытаНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.11.2024, 2:22