Aether
|
|
« : 26-02-2017 18:29 » |
|
Добрый вечер.
Вопрос вот такой, предположим мне необходимо создать файл большого размера под обработку, например, 20Гб, а свободного места на диске к началу процесса заполнения моего файла 40Гб - как бы хватает. Однако, другие процессы заполняют пространство быстрее моего, и получается ситуация, когда место на диске исчерпывается, и процесс прерывает расчёт в аварийном порядке. Так вот, можно ли создать файл и быстро зарезервировать под него место, например, эти 20Гб, но так, чтобы не тратить время на запись, например, нулями всего его пространства?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 26-02-2017 19:34 » |
|
1. ftruncate. Не уверен, что будет физическое занятие места. 2. Тупо заполнить нулями. 3. Воспользоваться специфичными для ОС вызовами для резервирования места (напр., ext4 поддерживает резервирование без фактической записи). Сам не пользовался, подозреваю это будет ioctl.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Ochkarik
|
|
« Ответ #2 : 26-02-2017 20:00 » |
|
в винде в консоли (стало интересно, нагуглил) fsutil file createnew <filename> <length> работает)
PS а вообще почему нельзя тупо переместить указатель на конец файла и записать туда допустим ноль?
|
|
« Последнее редактирование: 26-02-2017 20:03 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Aether
|
|
« Ответ #3 : 26-02-2017 20:37 » |
|
PS а вообще почему нельзя тупо переместить указатель на конец файла и записать туда допустим ноль?
Если речь о fseek, то предполагаю он вернёт ошибку - EINVAL, скорее всего, и всё, но попробую завтра. Я думаю, указатель позиции может существовать только в пределах уже имеющегося текущего габарита файла. 3. Воспользоваться специфичными для ОС вызовами для резервирования места (напр., ext4 поддерживает резервирование без фактической записи). Сам не пользовался, подозреваю это будет ioctl.
в винде в консоли (стало интересно, нагуглил) fsutil file createnew <filename> <length> работает)
То есть для NTFS может быть решение?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #4 : 26-02-2017 22:31 » |
|
Для Windows SetEndOfFile, SetFileValidData
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #5 : 26-02-2017 23:37 » |
|
ftruncate под Linux не занимает место на диске. $ df -m Filesystem 1M-blocks Used Available Use% Mounted on /dev/ploop34549p1 25069 1486 22287 7% / $ ./create_big_file $ ls -l total 16 -rwxr-xr-x 1 root root 8624 Feb 26 18:35 create_big_file -rw-r--r-- 1 root root 258 Feb 26 18:35 create_big_file.c -rwx--x--T 1 root root 1073741824 Feb 26 18:35 test.bin $ df -m Filesystem 1M-blocks Used Available Use% Mounted on /dev/ploop34549p1 25069 1486 22287 7% /
Выполнение мгновенное.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #6 : 27-02-2017 06:51 » |
|
Для того, чтобы место точно выделилось, имхо, в UNIX-подобных ОС необходимо использовать posix_fallocate(). Правда как у него со скоростью не знаю.
|
|
|
Записан
|
|
|
|
Aether
|
|
« Ответ #7 : 27-02-2017 10:11 » |
|
Буду знать, но, как понял ftruncate является частью unistd.h, а не stdio.h. Кстати, бегло прочёл, но вроде рекомендовано аккуратно её использовать ввиду того, что функция может быть не в курсе состояния буфера ввода-вывода. Я так понимаю, если обрезается файл с уже имеющимися данными, то необходимо перед её вызовом делать fflush. fseek выдаёт ошибку при попытке задать указатель, превышающий действительный размер файла. Для Windows SetEndOfFile, SetFileValidData
Похоже это оно, но читаю следующее: https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365544(v=vs.85).aspxBOOL WINAPI SetFileValidData( _In_ HANDLE hFile, _In_ LONGLONG ValidDataLength ); ... ValidDataLength [in] The new valid data length. This parameter must be a positive value that is greater than the current valid data length, but less than the current file size. ... То есть логически установить размер больший, чем есть нельзя. https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365531(v=vs.85).aspxThe physical file size is also referred to as the end of the file. The SetEndOfFile function can be used to truncate or extend a file. To set the logical end of a file, use the SetFileValidData function. ... BOOL WINAPI SetEndOfFile( _In_ HANDLE hFile ); ... The SetEndOfFile function sets the file size. Use SetFileValidData to set the valid data length. ...
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #8 : 27-02-2017 13:40 » |
|
Да можно и без SetEndOfFile, SetFileValidData - CreateFile, CreateFileMapping
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #9 : 27-02-2017 22:02 » |
|
$ df -m / Filesystem 1M-blocks Used Available Use% Mounted on /dev/ploop34549p1 25069 1487 22287 7% / $ time ./create_big_file_posix
real 0m0.005s user 0m0.000s sys 0m0.004s $ df -m / Filesystem 1M-blocks Used Available Use% Mounted on /dev/ploop34549p1 25069 2511 21262 11% / $ ls -l test.bin -rw-r--r-- 1 root root 1073741824 Feb 27 16:59 test.bin
Гиг мгновенно. Это 5 мс в виртуалке, а на хосте всего 1 мс. Вариант для 64 бита выделил 32 ГБ за 79 мс. Подтверждаю, что записи в блоки данных нет.
|
|
« Последнее редактирование: 27-02-2017 22:32 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #10 : 28-02-2017 08:24 » |
|
Гиг мгновенно. Это 5 мс в виртуалке, а на хосте всего 1 мс. Вариант для 64 бита выделил 32 ГБ за 79 мс. Подтверждаю, что записи в блоки данных нет.
Судя по man-ам, как я понимаю, это зависит от файловой системы. Если поддерживается, то всё будет работать довольно быстро и без ситуаций "гонок". Если не поддерживается, то будет включена эмуляция, которая может работать медленно и с "гонками".
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #11 : 28-02-2017 20:31 » |
|
ext4 - я еще парой постов выше написал. Еще поддерживается, как минимум, xfs и btrfs.
Интересный аспект: в Linux оно поддержано в ядре и по возможности поддерживается железом. Место не просто аллоцируется, но и заполняется нулями.
|
|
« Последнее редактирование: 28-02-2017 21:12 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #12 : 01-03-2017 07:58 » |
|
ext4 - я еще парой постов выше написал. Еще поддерживается, как минимум, xfs и btrfs.
Я это больше не Вам, а топикстартеру, что-бы он понимал, что могут быть определённые ньюансы при использовании этой функции.
|
|
|
Записан
|
|
|
|
Aether
|
|
« Ответ #13 : 01-03-2017 09:29 » |
|
Интересный аспект: в Linux оно поддержано в ядре и по возможности поддерживается железом. Место не просто аллоцируется, но и заполняется нулями.
Если учесть сколько времени шла запись гигабайтов, то записи этих данных не происходило, значит, место, полагаю, нулями физически не заполняется, просто попытка прочесть из зарезервированного пространства будет возвращать нуль. Интересно также: резервируя место система выделяет конкретные блоки, или просто из "счётчика свободного пространства" вычитает наш размер, и заранее остаётся неизвестным где будут лежать блоки файла при его наполнении?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #14 : 01-03-2017 19:58 » |
|
Все верно. iostat показал менее 1.5 МБ записанного. Значит зануление региона поддерживается файловой системой. Но есть еще операция FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, вызывающая аппаратный ATA TRIM и SCSI DISCARD.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|