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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> запись множества файлов без фрагментов, как освободить место под целый файл? 
V
    Опции темы
bems
Дата 29.7.2011, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



asmdzen, я знаю винапи, но совершенно не знаю плюсов smile
но вот какая-то open из io.h вроде возвращает хендл


--------------------
Обижено школьников: 8
PM MAIL   Вверх
asmdzen
Дата 29.7.2011, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



нашел кое что интересное - boost::filesystem::resize_file(const path& p, uintmax_t new_size);
работает как truncate
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



Цитата(asmdzen @  29.7.2011,  15:45 Найти цитируемый пост)
boost::filesystem::resize_file(const path& p, uintmax_t new_size);

оО..

буду знать smile

PM WWW   Вверх
asmdzen
Дата 29.7.2011, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



Цитата(asmdzen @  29.7.2011,  15:45 Найти цитируемый пост)
boost::filesystem::resize_file

вот только и она и file_size требуют не хэндл а имя файла, получается что если файл уже открыт (ofstream и open) то выдает ошибку типа:
Цитата
'boost::filesystem3::filesystem_e
rror'
  what():  boost::filesystem::resize_file: The operation completed successfully:
 "myfile.txt"

такую же ошибку получаем и в случае атрибута "только чтение" у файла.
неужто придется закрыть файл после создания, изменить размер и опять открыть?
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



Цитата(asmdzen @  29.7.2011,  18:00 Найти цитируемый пост)
неужто придется закрыть файл после создания, изменить размер и опять открыть?

конечно. ведь дескриптор файла уже во владении.
а что, нет возможности определить необходимый размер файла до операций с ним?

Добавлено через 4 минуты и 19 секунд
хотя сообщение в ислючении говорит что операция завершилась успехом smile 
оберни этот вызов в try-catch, и посмотри, файл изменяет свой размер?
но в любом случае изменять размер файла который уже используется, как-то не правильно. его размер может изменять использующий его код.
PM WWW   Вверх
asmdzen
Дата 29.7.2011, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



Цитата(boostcoder @  29.7.2011,  18:12 Найти цитируемый пост)
а что, нет возможности определить необходимый размер файла до операций с ним?

я его создаю, так что приходится создать, закрыть, изменить размер, опять открыть уже для записи.
пробовал создать файл на 10ГБ, не заметил абсолютно никакой нагрузки, хотя файл был заполнен нолями ))

Цитата(boostcoder @  29.7.2011,  18:12 Найти цитируемый пост)
оберни этот вызов в try-catch

есть версия resize_file которая получает в качестве параметра ссылку на boost::system::error_code
и возвращает в нем код ошибки, но размер файла не меняется все равно.

осталось найти как увеличить выходной буфер записи данных в файл )
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



Цитата(asmdzen @  29.7.2011,  20:02 Найти цитируемый пост)
я его создаю, так что приходится создать, закрыть, изменить размер, опять открыть уже для записи.

ну так определи необходимый размер и потом создавай.

Цитата(asmdzen @  29.7.2011,  20:02 Найти цитируемый пост)
хотя файл был заполнен нолями

откуда мнение что он чем-то должен заполняться?

Цитата(asmdzen @  29.7.2011,  20:02 Найти цитируемый пост)
осталось найти как увеличить выходной буфер записи данных в файл )

fstream.rdbuf()->pubsetbuf(ptr, size);
PM WWW   Вверх
asmdzen
Дата 29.7.2011, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



Цитата(boostcoder @  29.7.2011,  20:11 Найти цитируемый пост)
ну так определи необходимый размер и потом создавай.

разве можно создать файл сразу с определенным размером??  smile 

Цитата(boostcoder @  29.7.2011,  20:11 Найти цитируемый пост)
откуда мнение что он чем-то должен заполняться?

да нет, это спецификация resize_file, т.е. он и должен быть заполнен нолями, я писал что никакой нагрузки не заметил когда он заполнялся )
Цитата(boostcoder @  29.7.2011,  20:11 Найти цитируемый пост)
fstream.rdbuf()->pubsetbuf(ptr, size); 

большое спасибо. т.е. я создаю этот буфер (насколько понял можно и перед открытием файла)? при уничтожении fstream'а он освободится?

Это сообщение отредактировал(а) asmdzen - 29.7.2011, 20:29
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



Цитата(asmdzen @  29.7.2011,  20:23 Найти цитируемый пост)
разве можно создать файл сразу с определенным размером??

нет. создаешь файл. изменяешь его размер. и пишешь в него! smile 

Цитата(asmdzen @  29.7.2011,  20:23 Найти цитируемый пост)
 это спецификация resize_file, т.е. он и должен быть заполнен нолями

пруф, пожалуйста.

Цитата(asmdzen @  29.7.2011,  20:23 Найти цитируемый пост)
 я создаю этот буфер (насколько понял можно и перед открытием файла)? при уничтожении fstream'а он освободится?

сам выделяешь, и сам освобождаешь. или используй смарт-поинтер.
Код

std::ofstream of(...);
boost::shared_array<char> buf(new char[size]);
of.rdbuf()->pubsetbuf(buf.get(), size);

PM WWW   Вверх
asmdzen
Дата 29.7.2011, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



Цитата(boostcoder @  29.7.2011,  20:55 Найти цитируемый пост)
пруф, пожалуйста.

Цитата(http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/reference.html#resize_file)
Remarks: Achieves its postconditions as if by POSIX truncate().

Цитата(http://pubs.opengroup.org/onlinepubs/000095399/functions/truncate.html)
If the file was previously shorter than length, its size is increased, and the extended area appears as if it were zero-filled.

файл и в самом деле был заполнен нолями )
всем спасибо, вопрос считаю закрытым.
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



кросплатформенный вариант:
Код

#include <cstdint>

int resize_file(const char* path, uint64_t size) {
#ifdef _WIN32
#include <windows.h>

   HANDLE file = CreateFileA(
      path, // FileName
      GENERIC_WRITE, // DesiredAccess
      FILE_SHARE_READ|FILE_SHARE_WRITE, // ShareMode
      0, // SecurityAttributes
      OPEN_EXISTING, // CreationDisposition
      FILE_ATTRIBUTE_NORMAL, // FlagsAndAttributes
      0 // TemplateFile
   );
   if ( file == INVALID_HANDLE_VALUE ) return GetLastError();
   
   LARGE_INTEGER lsize;
   lsize.QuadPart = size;
   
   if ( SetFilePointer(file, lsize.LowPart, &lsize.HighPart, FILE_BEGIN) == INVALID_SET_FILE_POINTER )
      return GetLastError();
   if ( !SetEndOfFile(file) )
      return GetLastError();

#elif __linux__
#include <unistd.h>
#include <sys/types.h>

   if ( truncate(file, size) ) {
      return errno;
   }

#else
#   error "You`r platform is not supported!"
#endif

   return 0;
}



Добавлено @ 21:32
у меня немного иначе написано.
user posted image

в общем, могу смело утверждать одно: никакое расширенное пространство нулями не заполняется. ибо сейчас я расширил файл до 100Гб, и операция завершилась мгновенно.
предполагаю, что при чтении из расширенного пространства ты читаешь нули потому, что ОС реально с диска ничего не читает, ибо знает, что эта область зарезервирована и в нее ничего никогда не писалось.


Это сообщение отредактировал(а) boostcoder - 29.7.2011, 21:35
PM WWW   Вверх
boostcoder
Дата 29.7.2011, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



так и есть. прочитал расширенных 100Гб, и никакой активности на HDD не возникло smile
PM WWW   Вверх
asmdzen
Дата 29.7.2011, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

Репутация: 3
Всего: 5



Цитата(boostcoder @  29.7.2011,  21:26 Найти цитируемый пост)
предполагаю, что при чтении из расширенного пространства ты читаешь нули потому, что ОС реально с диска ничего не читает, ибо знает, что эта область зарезервирована и в нее ничего никогда не писалось.

видимо так и есть, я просто предпологал что туда что-то пишется из-за этого 
Цитата(http://msdn.microsoft.com/en-us/library/aa365531%28v=vs.85%29.aspx)
If the file is extended, the contents of the file between the old end of the file and the new end of the file are not defined.

т.е. я думал что это похоже на операцию malloc, а в линуксе еще выполняется ZeroMemory )


Цитата(boostcoder @  29.7.2011,  21:44 Найти цитируемый пост)
так и есть. прочитал расширенных 100Гб, и никакой активности на HDD не возникло

не могу понять как это возможно
Цитата
Size: 9,53 MB (10 000 000 bytes)
Size on disk: 9,53 MB (10 002 432 bytes)

т.е. файл реально существует, может это файловая система такое вытворяет, типа метод сжатия, но почему размер показывает нормально?


Это сообщение отредактировал(а) asmdzen - 29.7.2011, 22:19
PM MAIL   Вверх
boostcoder
Дата 29.7.2011, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 20
Всего: 110



Цитата(asmdzen @  29.7.2011,  22:17 Найти цитируемый пост)
не могу понять как это возможно

написал же выше:
Цитата(boostcoder @  29.7.2011,  21:26 Найти цитируемый пост)
при чтении из расширенного пространства ты читаешь нули потому, что ОС реально с диска ничего не читает, ибо знает, что эта область зарезервирована и в нее ничего никогда не писалось.


Добавлено через 1 минуту и 22 секунды
по идее блоки которые добавились, имеют какой-то атрибут, который ядро проверяет при чтении. смысл читать то, куда никто и никогда не писал? smile все логично.
PM WWW   Вверх
volatile
Дата 30.7.2011, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 16
Всего: 85



Это фича файловой системы. Называется sparse file.

на NTFS можно установить у любого файла флаг разрешающий/запрещающий эту фичу.
на старых файловых системах (FAT,FAT32) такое не поддерживается.
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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