[linux] How to create a file with a given size in Linux?

For testing purposes I have to generate a file of a certain size (to test an upload limit).

What is a command to create a file of a certain size on Linux?

This question is related to linux command-line

The answer is


There are lots of answers, but none explained nicely what else can be done. Looking into man pages for dd, it is possible to better specify the size of a file.

This is going to create /tmp/zero_big_data_file.bin filled with zeros, that has size of 20 megabytes :

    dd if=/dev/zero of=/tmp/zero_big_data_file.bin  bs=1M count=20

This is going to create /tmp/zero_1000bytes_data_file.bin filled with zeros, that has size of 1000 bytes :

    dd if=/dev/zero of=/tmp/zero_1000bytes_data_file.bin  bs=1kB count=1

or

    dd if=/dev/zero of=/tmp/zero_1000bytes_data_file.bin  bs=1000 count=1

  • In all examples, bs is block size, and count is number of blocks
  • BLOCKS and BYTES may be followed by the following multiplicative suffixes: c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M GB =1000*1000*1000, G =1024*1024*1024, and so on for T, P, E, Z, Y.

Just to follow up Tom's post, you can use dd to create sparse files as well:

dd if=/dev/zero of=the_file bs=1 count=0 seek=12345

This will create a file with a "hole" in it on most unixes - the data won't actually be written to disk, or take up any space until something other than zero is written into it.


This will generate 4 MB text file with random characters in current directory and its name "4mb.txt" You can change parameters to generate different sizes and names.

base64 /dev/urandom | head -c 4000000 > 4mb.txt

Some of these answers have you using /dev/zero for the source of your data. If your testing network upload speeds, this may not be the best idea if your application is doing any compression, a file full of zeros compresses really well. Using this command to generate the file

 dd if=/dev/zero of=upload_test bs=10000 count=1

I could compress upload_test down to about 200 bytes. So you could put yourself in a situation where you think your uploading a 10KB file but it would actually be much less.

What I suggest is using /dev/urandom instead of /dev/zero. I couldn't compress the output of /dev/urandom very much at all.


dd if=/dev/zero of=my_file.txt count=12345

you could do:

[dsm@localhost:~]$ perl -e 'print "\0" x 100' > filename.ext

Where you replace 100 with the number of bytes you want written.


On OSX (and Solaris, apparently), the mkfile command is available as well:

mkfile 10g big_file

This makes a 10 GB file named "big_file". Found this approach here.


As shell command:

< /dev/zero head -c 1048576 >  output

You can do it programmatically:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main() {
    int fd = creat("/tmp/foo.txt", 0644);
    ftruncate(fd, SIZE_IN_BYTES);
    close(fd);
    return 0;
}

This approach is especially useful to subsequently mmap the file into memory.

use the following command to check that the file has the correct size:

# du -B1 --apparent-size /tmp/foo.txt

Be careful:

# du /tmp/foo.txt

will probably print 0 because it is allocated as Sparse file if supported by your filesystem.

see also: man 2 open and man 2 truncate


Use fallocate if you don't want to wait for disk.

Example:

fallocate -l 100G BigFile

Usage:

Usage:
 fallocate [options] <filename>

Preallocate space to, or deallocate space from a file.

Options:
 -c, --collapse-range remove a range from the file
 -d, --dig-holes      detect zeroes and replace with holes
 -i, --insert-range   insert a hole at range, shifting existing data
 -l, --length <num>   length for range operations, in bytes
 -n, --keep-size      maintain the apparent size of the file
 -o, --offset <num>   offset for range operations, in bytes
 -p, --punch-hole     replace a range with a hole (implies -n)
 -z, --zero-range     zero and ensure allocation of a range
 -x, --posix          use posix_fallocate(3) instead of fallocate(2)
 -v, --verbose        verbose mode

 -h, --help           display this help
 -V, --version        display version

Use this command:

dd if=$INPUT-FILE of=$OUTPUT-FILE bs=$BLOCK-SIZE count=$NUM-BLOCKS

To create a big (empty) file, set $INPUT-FILE=/dev/zero.
Total size of the file will be $BLOCK-SIZE * $NUM-BLOCKS.
New file created will be $OUTPUT-FILE.


Please, modern is easier, and faster. On Linux, (pick one)

truncate -s 10G foo
fallocate -l 5G bar

It needs to be stated that truncate on a file system supporting sparse files will create a sparse file and fallocate will not. A sparse file is one where the allocation units that make up the file are not actually allocated until used. The meta-data for the file will however take up some considerable space but likely no where near the actual size of the file. You should consult resources about sparse files for more information as there are advantages and disadvantages to this type of file. A non-sparse file has its blocks (allocation units) allocated ahead of time which means the space is reserved as far as the file system sees it. Also fallocate nor truncate will not set the contents of the file to a specified value like dd, instead the contents of a file allocated with fallocate or truncate may be any trash value that existed in the allocated units during creation and this behavior may or may not be desired. The dd is the slowest because it actually writes the value or chunk of data to the entire file stream as specified with it's command line options.

This behavior could potentially be different - depending on file system used and conformance of that file system to any standard or specification. Therefore it is advised that proper research is done to ensure that the appropriate method is used.


You can do it programmatically:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main() {
    int fd = creat("/tmp/foo.txt", 0644);
    ftruncate(fd, SIZE_IN_BYTES);
    close(fd);
    return 0;
}

This approach is especially useful to subsequently mmap the file into memory.

use the following command to check that the file has the correct size:

# du -B1 --apparent-size /tmp/foo.txt

Be careful:

# du /tmp/foo.txt

will probably print 0 because it is allocated as Sparse file if supported by your filesystem.

see also: man 2 open and man 2 truncate