Как создать файл точного размера
В каждой системе для этого есть команда, и все три приведены ниже. Они дают файл с точным числом байт, а для многих тестов этого достаточно. Каждая команда на этой странице была выполнена до публикации в той системе, к которой она относится.
Короткий ответ
Windows: fsutil file createnew name 10485760. Linux: dd if=/dev/zero of=name
bs=1M count=10. macOS: mkfile 10m name. Размеры указываются в байтах, а 10
МБ, посчитанные так, как считает ваш файловый менеджер, - это 10485760.
Windows
fsutil и вариант на PowerShell, которому ничего дополнительного не нужно
fsutil входит в Windows. Он принимает размер в байтах, поэтому сначала
посчитайте число: 10 МБ - это 10485760, 100 МБ - 104857600, 1 ГБ - 1073741824.
fsutil file createnew test10mb.bin 10485760
Измерено в Windows 11: работает из обычной командной строки без повышенных прав, и файл получается ровно в 10485760 байт.
PowerShell может сделать то же самое, не вызывая другую программу, и понимает единицы:
$file = New-Object System.IO.FileStream "test10mb.bin", Create, ReadWrite
$file.SetLength(10MB)
$file.Close()
10MB в PowerShell означает 10485760 байт, тот же счёт по основанию 1024, что использует
Проводник, поэтому две команды выше дают один и тот же размер.
Linux
dd, truncate и fallocate, и разница, которая ловит людей
dd знают все. Он действительно записывает байты:
dd if=/dev/zero of=test10mb.bin bs=1M count=10
truncate срабатывает мгновенно, и в этом подвох. Измерено в Alpine Linux: файл сообщает
10485760 байт и занимает ноль блоков - это разреженный файл.
Всё, что его читает, получает десять мегабайт нулей, но диск место так и не отдал:
truncate -s 10M test10mb.bin
Для проверки лимита загрузки это нормально, а для проверки дисковой квоты вводит в заблуждение.
fallocate - то, к чему стоит обратиться, когда место должно быть настоящим:
fallocate -l 10M test10mb.bin
А когда содержимое должно быть несжимаемым, чтобы архиватор не мог снова его ужать:
head -c 10485760 /dev/urandom > test10mb.bin
macOS
mkfile, который не разреженный, и две команды, которые вы уже знаете
В macOS есть mkfile. Измерено в macOS 26.6.2: 10485760 байт и 20480 блоков, то есть
место действительно выделено, а не обещано:
mkfile 10m test10mb.bin
dd и truncate тоже есть и ведут себя как в Linux:
dd if=/dev/zero of=test10mb.bin bs=1m count=10
truncate -s 10M test10mb.bin
Где это перестаёт работать
Файл правильного размера - не файл правильного вида
Всё сказанное выше даёт блок нулей. Этого достаточно, когда тестируемое смотрит только на размер: лимит загрузки, квота, передача. Этого перестаёт хватать, как только что-либо открывает файл.
Измерено, и стоит проверить самому: сделайте файл на 2 МБ командой fsutil, назовите его
photo.png и передайте библиотеке работы с изображениями. Pillow ответит
cannot identify image file. Это не PNG. Он им никогда и не был, так говорило лишь
имя.
Это важнее, чем кажется, из-за того, в какую сторону тест тогда проваливается. Ваша точка загрузки отклоняет файл, ваш тест зеленеет, и вы заключаете, что лимит размера работает. Она отклонила его не из-за размера. Она отклонила его потому, что байты не были изображением, и правило, которое вы хотели проверить, так и не было достигнуто.
- парсер отклоняет его, не дойдя до каких-либо правил размера
- шаг создания миниатюры падает, и ошибка, которую вы читаете, относится к миниатюре
- антивирус или проверка содержимого отклоняет его по третьей причине
- просмотрщик ничего не показывает, и никто не может сказать, в этом ли ошибка
Другой путь
Настоящий файл этого формата точно того размера, который вы запросили
Именно это делает Testing Files Generator. Файл - настоящий файл своего формата, он открывается в своей программе, и в нём ровно то число байт, которое вы запросили, с точностью до байта:
tfg generate --format png --size 10mb --out ./fixtures
Запросите размер, которого формат не может достичь, и вы получите ошибку с названием минимума и причиной, а не файл неверного размера. Страница форматов перечисляет каждый формат с наименьшим файлом, который он может создать.
А лимит - это три тестовых случая, а не один, поэтому инструмент собирает все три:
tfg generate --format pdf --boundary 10mb --out ./edges
Вы получите 10485759, 10485760 и 10485761 байт и манифест, который говорит, какие из них ваша система должна принять, а какие отклонить. Страница сценариев разбирает это и ещё четыре задачи, для которых инструмент создан.
Бесплатно, открытый код, GPL-3.0. Без регистрации. Сборки для Windows и macOS подписаны и запускаются без предупреждений.
Так что же использовать?
-
Используйте системную команду
Когда ничто не открывает файл. Проверка лимита размера на точке, которая сначала смотрит размер, передача, квота, переполнение диска. Это одна строка, и она уже установлена.
-
Используйте настоящий генератор
Когда что-либо разбирает, отображает, импортирует или распаковывает файл - и когда завтра на другой машине нужны те же фикстуры, байт в байт.
Обе есть на этой странице, потому что обе бывают правы. Ошибка, которой стоит избегать, - использовать первую там, где нужна вторая, и принимать зелёный тест за доказательство.