Crie rapidamente um arquivo grande em um sistema Linux

438

Como posso criar rapidamente um arquivo grande em um sistema Linux ( Red Hat Linux )?

O dd fará o trabalho, mas a leitura /dev/zeroe a gravação na unidade podem demorar muito tempo, quando você precisar de um arquivo com várias centenas de GBs de tamanho para teste ... Se você precisar fazer isso repetidamente, o tempo realmente aumentará.

Não ligo para o conteúdo do arquivo, apenas quero que ele seja criado rapidamente. Como isso pode ser feito?

Usar um arquivo esparso não funcionará para isso. Eu preciso que o arquivo seja alocado em espaço em disco.

DrStalker
fonte
1
O Ext4 tem um desempenho de alocação de arquivos muito melhor, pois blocos inteiros de até 100 MB podem ser alocados de uma só vez.
martinus
5
O comando 'truncar' cria um arquivo esparso, a propósito. Por exemplo, veja en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
As pessoas parecem estar ignorando grosseiramente o "arquivo esparso não funcionará com isso", com suas buscas truncadas e dd abaixo.
Hpavc
1
Você deveria ter definido o que quis dizer com "para teste". Testando a velocidade de gravação do seu disco rígido? Testando o dfque reportará? Testando um aplicativo que faz algo em particular. A resposta depende do que você deseja testar. De qualquer forma eu sou um pouco tarde - Vejo agora que tem sido anos desde a sua pergunta :-)
ndemou
1
Apenas no caso de você estar procurando uma maneira de simular uma partição completa, como eu estava, não procure mais do que / dev / full #
Julian

Respostas:

509

dddas outras respostas é uma boa solução, mas é lenta para esse fim. No Linux (e em outros sistemas POSIX), temos fallocate, que usa o espaço desejado sem precisar gravá-lo, funciona com os sistemas de arquivos baseados em disco mais modernos, muito rapidamente:

Por exemplo:

fallocate -l 10G gentoo_root.img
Franta
fonte
5
É possível que o dd já esteja usando isso internamente? Se eu fizer dd se = / dev / zero de = zerofile bs = 1G count = 1 'em um kernel 3.0.0, a gravação termina em 2 segundos, com uma taxa de gravação de dados acima de 500 megabytes por segundo. Isso é claramente impossível em um disco rígido portátil de 2,5" .
lxgr
21
fallocateé exatamente o que eu estava procurando.
AB
7
Este ( fallocate) também não funcionará em um sistema de arquivos Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Joe
5
fallocate também não é suportado pelo ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
No Debian, o GNU / Linux fallocatefaz parte do util-linuxpacote. Esta ferramenta foi escrito por Karel Zak da RedHat e código-fonte pode ser encontrada aqui: kernel.org/pub/linux/utils/util-linux
Franta
295

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

O dd é a primeira opção óbvia, mas o dd é essencialmente uma cópia e obriga a escrever todos os blocos de dados (assim, inicializando o conteúdo do arquivo) ... E é essa inicialização que ocupa tanto tempo de E / S. (Deseja demorar ainda mais? Use / dev / random em vez de / dev / zero ! Então você usará a CPU e o tempo de E / S!) No final, porém, dd é uma má escolha (embora essencialmente o 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 opção - e provavelmente é a mais rápida ... Mas isso é porque cria um "arquivo esparso". Essencialmente, um arquivo esparso é uma seção do disco que possui muitos dos mesmos dados, e o sistema de arquivos subjacente "trapaceia" ao não armazenar realmente todos os dados, mas apenas "fingindo" que está tudo lá. Portanto, quando você usa truncado para criar uma unidade de 20 GB para sua VM, o sistema de arquivos não aloca 20 GB, mas trapaceia e diz que existem 20 GB de zeros lá, mesmo que apenas uma faixa no disco pode realmente (realmente) estar em uso. Por exemplo:

 truncate -s 10G gentoo_root.img

fallocate é o final - e melhor - escolha para uso com alocação de disco VM, porque é essencialmente "reservas" (ou "aloca" todo o espaço que você está procurando, mas ele não se preocupou em escrever qualquer coisa Então,. quando você usa fallocate para criar um espaço de unidade virtual de 20 GB, você realmente obtém um arquivo de 20 GB (não um "arquivo esparso" e não se preocupa em escrever nada nele - o que significa que praticamente qualquer coisa pode estar presente) lá - como um disco totalmente novo!) Por exemplo:

fallocate -l 10G gentoo_root.img
Dan McAllister
fonte
4
+1 truncateé funcional no JFS; fallocate, não muito. Um ponto: você não pode incluir um número decimal no número, eu precisava especificar 1536G, não 1.5T.
Calrion 11/09/14
1
Segundo a minha fallocatepágina do homem, isso só é suportado em btrfs, ext4, ocfs2e xfssistemas de arquivos
Nathan S. Watson-Haigh
Nota: swaponinfelizmente não funciona em extensões pré-alocadas, a última vez que verifiquei. Houve alguma discussão na lista de discussão do XFS sobre ter uma opção de fallocate para expor os dados antigos do espaço livre e não ter a extensão marcada como pré-alocada, para que o swapon funcionasse. Mas acho que nada foi feito.
Peter Cordes
1
Para sua informação, tentar ler muitos dados /dev/randompode resultar na falta de dados aleatórios e "Quando o pool de entropia estiver vazio, as leituras de / dev / random serão bloqueadas até que o ruído ambiental adicional seja coletado", portanto, pode levar muito, muito, muito muito tempo
Xen2050
154

Linux e todos os sistemas de arquivos

xfs_mkfile 10240m 10Gigfile

Linux e alguns sistemas de arquivos (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 <size>myfile como uma alternativa ao dd. Com a -nopção, o tamanho é anotado, mas os blocos de disco não são alocados até que os dados sejam gravados neles. Sem a -nopção, o espaço é preenchido com zero, o que significa gravar no disco, o que significa levar tempo.

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

A maioria dos sistemas Linux também possui fallocate, que funciona apenas em determinados sistemas de arquivos (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 nenhum disso.

CMS
fonte
5
Onde está esse arquivo do qual você fala, mais estranho? Não está na instalação padrão do RHEL.
paxdiablo
2
É um utilitário solaris. se você procurar gpl mkfile, encontrará alguns exemplos de código fonte.
Martin Beckett
5
Funciona como um charme no OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfileestá incluído no xfsprogs no Ubuntu e funciona como um encanto no meu ext3 fs. :)
Greg Dubicki
97
truncate -s 10M output.file

criará um arquivo de 10 M instantaneamente (M significa 1024 * 1024 bytes, MB significa 1000 * 1000 - o mesmo com K, KB, G, GB ...)

EDIT: como muitos apontaram, isso não alocará fisicamente o arquivo no seu dispositivo. Com isso, é possível criar um arquivo grande arbitrário, independentemente do espaço disponível no dispositivo, pois ele cria um arquivo "esparso".

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 memória, talvez não tenha o desempenho esperado.

Mas este ainda é um comando útil para saber

kiv
fonte
1
Tentei isso, mas não afeta o espaço em disco disponível. Deve, porque é um arquivo esparso, conforme descrito anteriormente.
Gringo Suave
7
Esta não deve ser a resposta principal, pois não resolve o problema, a fallocateresposta abaixo sim.
Gringo Suave
4
@GringoSuave, mas isso ainda é útil para algumas pessoas que podem ter um problema semelhante, mas um pouco diferente.
AJMansfield
@GringoSuave: Parece criar um arquivo grande, conforme solicitado, por que não resolve o problema? Além disso, existem notas na resposta de fallocate que nem sequer funcionam na maioria dos casos.
Pavel Šimerda
1
Por que sugerir criar arquivos esparsos quando ele disse que não funcionaria?
Hpavc
44

Onde procurar é o tamanho do arquivo que você deseja em bytes - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Zoredache
fonte
6
Eu gosto dessa abordagem, mas o comentarista não quer um arquivo esparso por algum motivo. :(
ephemient
3
dd if = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien
7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret
1
Para arquivos esparsos, truncateparece ser muito melhor.
Pavel Šimerda
36

Exemplos em que procurar é 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


Na página de manual do dd:

BLOCOS 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.

Sepero
fonte
Isso parece muito melhor do que o modo n-1 , então é basicamente equivalente a truncate.
Pavel Šimerda
19

Para criar um arquivo de 1 GB:

dd if=/dev/zero of=filename bs=1G count=1
max
fonte
7
Eu acredito que a contagem deve ser 1. (testado em centos)
SvennD
dd if=/dev/zero of=filename bs=20G count=1criará apenas arquivos de 2 GB! não 20GB.
Maulik Gangani
18

Não sei muito sobre o Linux, mas aqui está o código C que escrevi para falsificar grandes arquivos 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");
    }
}
Hipopótamo Humungoso
fonte
deve haver abordagens melhores em C. Você também precisa fechar o arquivo. Iterando para um milhão de caracteres escritos 1 por vez ...
ACV
10

Você pode usar o comando "yes" também. A sintaxe é bastante simples:

#yes >> myfile

Pressione "Ctrl + C" para interromper isso, caso contrário, ele consumirá todo o seu espaço disponível.

Para limpar este arquivo, execute:

#>myfile

irá limpar este arquivo.

Yogi
fonte
7

Eu não acho que você vai ficar muito mais rápido que o dd. O gargalo é o disco; gravar centenas de GB de dados nele vai demorar muito, 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 canal para um programa externo. O programa externo gera dados sempre que necessário. Uma vez que o canal está aberto, ele age como um arquivo comum, pois o programa que abriu o canal pode fseek (), rebobinar (), etc. Você precisará usar pclose () em vez de close () quando estiver feito com o cano.

Se o seu aplicativo precisar que o arquivo tenha um determinado tamanho, caberá ao programa externo acompanhar onde está o "arquivo" e enviar um eof quando o "final" for atingido.

Barry Brown
fonte
4

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

Por exemplo, tenha um conjunto de arquivos chamado:

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

Então, se você tiver um aplicativo que precise 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ê precisará 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 do link é o mais rápido possível.

paxdiablo
fonte
Você pode ter uma pequena piscina ou uma piscina grande, a escolha é sua. Você precisaria de pelo menos um arquivo de qualquer maneira, já que foi o que o interlocutor pediu. Se seu pool consistir em um arquivo, você não perderá nada. Se você possui cargas de disco (e deveria, devido ao seu baixo preço), não há problema.
23468
3

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

Na ausência de uma chamada de sistema que realmente aloque espaço para um arquivo sem gravar dados (e o Linux e o BSD não possuem isso, provavelmente o 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 memória e grave dados diferentes de zero nos primeiros bytes de cada bloco de disco (use fgetconf para encontrar o tamanho do bloco de disco).

Alex Dupuy
fonte
4
BSD e Linux, na verdade, têm fallocate (editar: agora é POSIX e amplamente disponível).
Tobu
3

Plugue descarado: O OTFFS fornece um sistema de arquivos que fornece arquivos arbitrariamente grandes (bem, quase. Exabytes é o limite atual) de conteúdo gerado. É somente Linux, C simples e no início do alfa.

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

Stefan
fonte
3

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

  • O objetivo do arquivo grande é preencher um disco, portanto não pode ser compactado.
  • Usando o sistema de arquivos ext3. ( fallocatenã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 incorporado e isso funciona bem o suficiente, mas prefere algo mais rápido.

Para sua informação, o comando dd if=/dev/urandom of=outputfile bs=1024 count = XXera tão lento que não podia ser utilizado.

user79878
fonte