Crie rapidamente um arquivo grande em um sistema Linux?

Como posso criar rapidamente um arquivo grande em um sistema Linux ( Red Hat Linux )? dd fará o trabalho, mas a leitura de /dev/zero e a gravação na unidade podem levar muito tempo quando você precisar de um arquivo com centenas de GBs em tamanho para teste … Se você precisar fazer isso repetidamente, o tempo realmente acrescenta-se.

Eu não me importo com o conteúdo do arquivo, só quero que ele seja criado rapidamente. Como isso pode ser feito?

Usando um arquivo esparso não vai funcionar para isso. Eu preciso do arquivo a ser alocado espaço em disco.

    dd é uma boa solução, mas é lenta para esse propósito. No Linux, nós temos o fallocate .

    Por exemplo:

     fallocate -l 10G gentoo_root.img 

    Essa é uma pergunta comum – especialmente no ambiente atual de ambientes virtuais. Infelizmente, a resposta não é tão direta quanto se poderia supor.

    dd é a primeira escolha óbvia, mas dd é essencialmente uma cópia e isso força você a escrever cada bloco de dados (assim, inicializando o conteúdo do arquivo) … E essa boot é o que ocupa muito tempo de E / S. (Quer fazer com que demore mais? Use / dev / random em vez de / dev / zero ! Então você usará a CPU assim como o tempo de E / S!) No final, dd é uma má escolha (embora padrão usado pela VM “criar” GUIs). Por exemplo:

     dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G 

    Truncar é outra escolha – e é provavelmente o mais rápido … Mas isso é porque ele cria um “arquivo esparso”. Essencialmente, um arquivo esparso é uma seção do disco que tem muitos dos mesmos dados, e o sistema de arquivos subjacente “trapaceia” por não armazenar realmente todos os dados, mas apenas “fingir” que está tudo lá. Assim, quando você usa o truncate para criar uma unidade de 20 GB para sua VM, o sistema de arquivos não aloca 20 GB, mas ele trapaceia e diz que há 20 GB de zeros lá, mesmo que apenas uma trilha no disco pode realmente (realmente) estar em uso. Por exemplo:

      truncate -s 10G gentoo_root.img 

    fallocate é a escolha final – e melhor – para uso com alocação de disco de VM, porque essencialmente “reserva” (ou “aloca” todo o espaço que você está procurando, mas não se preocupa em escrever nada. Então, quando você usa o fallocate para criar um espaço de disco virtual de 20 GB, você realmente obtém um arquivo de 20 GB (não um “arquivo esparso”, e não terá se incomodado em escrever nada nele – o que significa que praticamente qualquer coisa poderia estar lá – como um novo disco!) Por exemplo:

     fallocate -l 10G gentoo_root.img 

    Linux e todos os filesystems

    xfs_mkfile 10240m 10Gigfile

    Linux e alguns filesystems (ext4, xfs, btrfs e ocfs2)

    fallocate -l 10G 10Gigfile

    OS X, Solaris, SunOS e provavelmente outros UNIXes

    mkfile 10240m 10Gigfile

    HP-UX

    prealloc 10Gigfile 10737418240

    Explicação

    Tente mkfile myfile como uma alternativa do dd . Com a opção -n o tamanho é anotado, mas os blocos de disco não são alocados até que os dados sejam gravados neles. Sem a opção -n , o espaço é preenchido com zero, o que significa gravar no disco, o que significa tempo.

    O mkfile é derivado do SunOS e não está disponível em todos os lugares. A maioria dos sistemas Linux tem o xfs_mkfile que funciona exatamente da mesma maneira, e não apenas nos filesystems XFS, apesar do nome. Está incluído no xfsprogs (para Debian / Ubuntu) ou pacotes com nomes semelhantes.

    A maioria dos sistemas Linux também possui fallocate , que funciona apenas em determinados filesystems (como btrfs, ext4, ocfs2 e xfs), mas é o mais rápido, pois aloca todo o espaço no arquivo (cria arquivos não-holey), mas não inicializa nada disso.

     truncate -s 10M output.file 

    irá criar um arquivo de 10 M instantaneamente (M significa 1024 * 1024 bytes, MB significa 1000 * 1000 – mesmo com K, KB, G, GB …)

    EDIT: como muitos apontaram, isso não irá alocar fisicamente o arquivo no seu dispositivo. Com isso, você pode criar um arquivo grande e arbitrário, independentemente do espaço disponível no dispositivo

    Portanto, ao fazer isso, você estará adiando a alocação física até que o arquivo seja acessado. Se você estiver mapeando esse arquivo para a memory, talvez não tenha o desempenho esperado.

    Mas isso ainda é um comando útil para saber

    Onde seek é o tamanho do arquivo que você deseja em bytes – 1.

     dd if=/dev/zero of=filename bs=1 count=1 seek=1048575 

    Exemplos em que seek é o tamanho do arquivo que você deseja em bytes

     #kilobytes dd if=/dev/zero of=filename bs=1 count=0 seek=200K #megabytes dd if=/dev/zero of=filename bs=1 count=0 seek=200M #gigabytes dd if=/dev/zero of=filename bs=1 count=0 seek=200G #terabytes dd if=/dev/zero of=filename bs=1 count=0 seek=200T 

    Do dd manpage:

    BLOCKS e BYTES podem ser seguidos pelos seguintes sufixos multiplicativos: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 e assim por diante para T, P, E, Z, Y.

    Eu não sei muito sobre Linux, mas aqui está o código C que escrevi para falsificar arquivos enormes no DC Share há muitos anos.

     #include < stdio.h > #include < stdlib.h > int main() { int i; FILE *fp; fp=fopen("bigfakefile.txt","w"); for(i=0;i< (1024*1024);i++) { fseek(fp,(1024*1024),SEEK_CUR); fprintf(fp,"C"); } } 

    para fazer um arquivo 1G:

     dd if=/dev/zero of=filename bs=1G count=1 

    Você pode usar o comando “sim” também. A syntax é bem simples:

     #yes >> myfile 

    Pressione “Ctrl + C” para parar isso, senão ele vai devorar todo o seu espaço disponível.

    Para limpar este arquivo, execute:

     #>myfile 

    irá limpar este arquivo.

    Eu não acho que você vai ficar muito mais rápido que o dd. O gargalo é o disco; escrever centenas de GB de dados para ele vai levar muito tempo, não importa como você o faça.

    Mas aqui está uma possibilidade que pode funcionar para o seu aplicativo. Se você não se importa com o conteúdo do arquivo, que tal criar um arquivo “virtual” cujo conteúdo é a saída dinâmica de um programa? Em vez de abrir o arquivo, use popen () para abrir um pipe para um programa externo. O programa externo gera dados sempre que necessário. Uma vez que o pipe é aberto, ele age exatamente como um arquivo regular, pois o programa que abriu o pipe pode fseek (), rewind (), etc. Você precisará usar pclose () ao invés de close () quando estiver feito com o tubo.

    Se seu aplicativo precisar que o arquivo tenha um determinado tamanho, será responsabilidade do programa externo rastrear onde está o “arquivo” e enviar um eof quando o “fim” for atingido.

    Uma abordagem: se você puder garantir que aplicativos não relacionados usem os arquivos de maneira conflituosa, basta criar um pool de arquivos de tamanhos variados em um diretório específico e criar links para eles quando necessário.

    Por exemplo, tenha um pool de arquivos chamado:

    • / home / bigfiles / 512M-A
    • / home / bigfiles / 512M-B
    • / home / bigfiles / 1024M-A
    • / home / bigfiles / 1024M-B

    Então, se você tem um aplicativo que precisa de um arquivo 1G chamado / home / oracle / logfile, execute um ” ln /home/bigfiles/1024M-A /home/oracle/logfile “.

    Se estiver em um sistema de arquivos separado, você terá que usar um link simbólico.

    Os arquivos A / B / etc podem ser usados ​​para garantir que não haja uso conflitante entre aplicativos não relacionados.

    A operação de link é o mais rápida possível.

    O mkfile GPL é apenas um wrapper de script sh (ba) em torno de dd; O mkfile do BSD apenas configura um buffer com um valor diferente de zero e o grava repetidamente. Eu não esperaria que o primeiro superasse o dd. O último pode superar dd se = / dev / zero ligeiramente, uma vez que omite as leituras, mas qualquer coisa que seja significativamente melhor provavelmente está apenas criando um arquivo esparso.

    Ausente uma chamada de sistema que realmente aloca espaço para um arquivo sem gravar dados (e Linux e BSD não têm isso, provavelmente Solaris também) você pode obter uma pequena melhoria no desempenho usando ftrunc (2) / truncate (1) para estender o arquivo para o tamanho desejado, mapeie o arquivo na memory e, em seguida, grave dados diferentes de zero nos primeiros bytes de cada bloco de disco (use o fgetconf para localizar o tamanho do bloco de disco).

    Este é o mais rápido que eu pude fazer (o que não é rápido) com as seguintes restrições:

    • O objective do arquivo grande é preencher um disco, portanto, não pode ser compactado.
    • Usando o sistema de arquivos ext3. (não disponível)

    Esta é a essência disso …

     // include stdlib.h, stdio.h, and stdint.h int32_t buf[256]; // Block size. for (int i = 0; i < 256; ++i) { buf[i] = rand(); // random to be non-compressible. } FILE* file = fopen("/file/on/your/system", "wb"); int blocksToWrite = 1024 * 1024; // 1 GB for (int i = 0; i < blocksToWrite; ++i) { fwrite(buf, sizeof(int32_t), 256, file); } 

    `

    No nosso caso, isso é para um sistema Linux embutido e isso funciona bem, mas prefere algo mais rápido.

    FYI o comando "dd if = / dev / urandom de = outputfile bs = 1024 count = XX" era tão lento a ponto de ficar inutilizável.

    Plug desavergonhado: o OTFFS fornece um sistema de arquivos que fornece arquivos arbitrariamente grandes (bem, quase. Exabytes é o limite atual) de conteúdo gerado. É apenas Linux, C simples e no início alpha.

    Veja https://github.com/s5k6/otffs .

    Você pode facilmente baixar arquivos de teste de velocidade da OVH, é conveniente para testar a velocidade de download de arquivos.

    http://ovh.net/files/

     wget http://ovh.net/files/100Mio.dat 

    Muitos arquivos estão disponíveis, por exemplo:

    • 1 arquivo Gio = 1 gibioctet = 230 octetos = 1.024 Mio = 1.073.741.824 octetos
    • Arquivo de 10 Gbit = 10 gigabit = 1010 bits = 10.000 Mbit = 10.000.000.000 bits