Create a Dummy File of Any Size (Windows, macOS, Linux)
By Niks · Published · Updated
Tested on
- Windows 11 Home (10.0.22631), not elevated: fsutil, Windows PowerShell 5.1
- Git Bash with GNU coreutils 8.32: truncate, dd, head, stat, wc, gzip
- Not run by us: mkfile (macOS) and fallocate (Linux). Both are cited from their manual pages.
To create a dummy file of any size, use one command: fsutil file createnew test.bin 10485760 on Windows, truncate -s 10M test.bin on Linux, or mkfile -n 10m test.bin on macOS. Each makes a file of exactly the byte count you give it, with content that is zeros. That is enough to test upload limits, disk quotas and transfer speed, but not to test anything that reads the file’s contents, because a zero-filled file is not a valid PDF, ZIP or image.
Below are the commands we ran and the output we saw, the difference between sparse and fully written files, and when to reach for the dummy files generator instead.
Create a dummy file of any size on Windows
fsutil. Microsoft documents fsutil file createnew <filename> <length> as creating “a file of the specified name and size, with content that consists of zeroes”. We ran it from a normal, non-elevated prompt on Windows 11 (build 22631) and it worked:
> fsutil file createnew t_fsutil.bin 10485760
File C:\Users\...\t_fsutil.bin is created
Other Windows versions or policies may behave differently, and we did not test an older build. The length is in bytes, so 10 MiB is 10485760.
PowerShell. Open the file with .NET and set its length:
$f = [IO.File]::Create("$PWD\t_ps.bin"); $f.SetLength(10MB); $f.Close()
(Get-Item t_ps.bin).Length
10485760
10MB in PowerShell is 10,485,760 (binary; see KB vs KiB). Microsoft’s FileStream.SetLength documentation says that when a stream is extended, the contents between the old and new length are not defined on Windows, while on Linux that space is filled with zeros. We read the file back and it was 10,485,760 zero bytes (cmp against /dev/zero found no difference), but do not depend on that: if you need zeros, write them.
On Linux and macOS
truncate (GNU coreutils) sets a file to an exact length. The manual says a file that is extended gets a sparse extension that reads as zero bytes:
truncate -s 10M test.bin # 10 MiB = 10485760 bytes
truncate -s 10MB test.bin # 10,000,000 bytes
dd copies from a source in blocks. With GNU dd, bs=1M count=10 writes ten 1 MiB blocks:
$ dd if=/dev/zero of=t_dd.bin bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0040077 s, 2.6 GB/s
head can cut a byte count from any source, including random data:
head -c 10M /dev/urandom > random.bin # 10485760 bytes of random data
head -c 10485761 /dev/zero > n_plus_1.bin # any exact byte count
M is 1 MiB and MB is 1,000,000 in GNU tools (we checked: head -c 10M gives 10,485,760 bytes and head -c 10MB gives 10,000,000).
fallocate (Linux, util-linux) reserves real disk blocks quickly: fallocate -l 10M test.bin. Its man page says preallocation is done by allocating blocks and marking them as uninitialized, which is much faster than filling a file with zeros. We did not run it; it is not available in our Git Bash environment.
mkfile (macOS): mkfile -n 10m test.bin. The macOS man page says the size suffixes are b (512), k (1024), m (1048576) and g (1073741824), that files are padded with zeroes by default, and that -n creates an empty file whose size is noted but “disk blocks aren’t allocated until data is written to them”. We did not run it; we had no Mac. We also have not tested dd on macOS, whose option syntax can differ from GNU’s.
Sparse or fully written: check before you rely on it
A sparse file records its length but stores no blocks for the empty parts. It shows the size you asked for, uploads as that many zero bytes, and uses almost no disk. A fully written file uses the disk space. That difference decides whether a command is right for a disk-full or quota test.
We checked each file we made with fsutil sparse queryflag and fsutil file queryallocranges:
| Command | Reported size | Sparse flag | Allocated ranges (0 to 10 MiB) |
|---|---|---|---|
fsutil file createnew | 10485760 | not sparse | one range, 0xa00000 bytes |
PowerShell SetLength | 10485760 | not sparse | not queried |
GNU truncate (Git Bash) | 10485760 | sparse | none |
GNU dd (Git Bash) | 10485760 | not sparse | one range, 0xa00000 bytes |
So on this machine, truncate made a sparse file and the other commands did not. That result comes from the NTFS volume and the MSYS build of truncate we used; on Linux, ext4 and other file systems can behave differently. Test the file with your own tools before relying on either behaviour.
Sparse files are fine for upload size checks. They are wrong for anything that reads real disk or measures storage: quotas, backups, “disk full” behaviour.
Zeros or random data
A file of zeros compresses to almost nothing. We compressed our 10 MiB files with gzip -c:
10 MiB of zeros -> 10,217 bytes
10 MiB of random -> 10,487,389 bytes (larger than the input)
If anything between you and the server compresses the transfer (a proxy, a CDN, a backup tool), a zero-filled file finishes almost instantly and tells you nothing about bandwidth. Use head -c SIZE /dev/urandom for throughput tests. For pure size-limit tests either works.
Check the size you got
$ stat -c%s t_dd.bin # GNU
10485760
$ wc -c t_dd.bin # portable
10485760 t_dd.bin
PS> (Get-Item t_dd.bin).Length
10485760
Do this every time. A mix-up between M and MB, or between blocks and bytes in dd, is the usual reason a boundary test fails for the wrong reason.
When a plain file is not enough
Command-line files have no structure. Upload code that checks the file type will reject them. We ran file --mime-type on a zero-filled file and a random file, both named .pdf, and compared them with a real PDF from this site:
zeros.pdf: application/octet-stream
random.pdf: application/octet-stream
sample.pdf: application/pdf
Both fake PDFs are typed as generic binary data, because there is no %PDF- at the start. If your endpoint validates content, or a parser opens the file, you need a real one of the right size. Validating uploads by file signature explains what such checks look for, and the test file upload limits guide shows how to use exact-size files at a limit.
Try it
The Dummy PDF file, Dummy Excel file, Dummy ZIP file, Dummy TXT file and Dummy JSON file pages make files of a type your validator accepts, at the exact byte count you type (set the unit to B). They are built in your browser and nothing is uploaded.
Sources
Accessed 30 September 2026.
- Microsoft,
fsutil file: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-file - Microsoft,
FileStream.SetLength: https://learn.microsoft.com/en-us/dotnet/api/system.io.filestream.setlength - GNU coreutils manual,
truncate: https://www.gnu.org/software/coreutils/manual/html_node/truncate-invocation.html - GNU coreutils manual,
headanddd: https://www.gnu.org/software/coreutils/manual/html_node/head-invocation.html and https://www.gnu.org/software/coreutils/manual/html_node/dd-invocation.html - util-linux
fallocate(1): https://man7.org/linux/man-pages/man1/fallocate.1.html (not run by us) - Apple
mkfile(8): https://keith.github.io/xcode-man-pages/mkfile.8.html (not run by us) - All output shown: Windows 11 (10.0.22631), Windows PowerShell 5.1, GNU coreutils 8.32, file 5.48, 29 September 2026.