| 
			| 
					
						| 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 -mFilesystem        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).aspx BOOL 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).aspx The 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.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	|  |