Cree rápidamente un archivo grande en un sistema Linux

438

¿Cómo puedo crear rápidamente un archivo grande en un sistema Linux ( Red Hat Linux )?

dd hará el trabajo, pero leer /dev/zeroy escribir en la unidad puede llevar mucho tiempo cuando necesita un archivo de varios cientos de GB de tamaño para probar ... Si necesita hacerlo repetidamente, el tiempo realmente se acumula.

No me importa el contenido del archivo, solo quiero que se cree rápidamente. ¿Cómo se puede hacer esto?

Usar un archivo disperso no funcionará para esto. Necesito que se le asigne espacio en disco al archivo.

DrStalker
fuente
1
Ext4 tiene un rendimiento de asignación de archivos mucho mejor, ya que se pueden asignar bloques completos de hasta 100 MB a la vez.
martinus
55
El comando 'truncar' crea un archivo disperso, por cierto. Por ejemplo, ver en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
La gente parece ignorar groseramente el "archivo disperso no funcionará con esto", con sus búsquedas truncadas y dd a continuación.
hpavc
1
Debería haber definido lo que quería decir con "para probar". ¿Prueba la velocidad de escritura de su disco duro? Prueba de lo dfque informará? Probar una aplicación que hace algo en particular. La respuesta depende de lo que quieras probar. De todos modos, llego un poco tarde - Ahora veo que han pasado años desde su pregunta :-)
ndemou
1
En caso de que esté buscando una manera de simular una partición completa, como lo estaba yo, no busque más allá de / dev / full
Julian

Respuestas:

509

ddde las otras respuestas es una buena solución, pero es lenta para este propósito. En Linux (y otros sistemas POSIX), tenemos fallocate, que utiliza el espacio deseado sin tener que escribir realmente, funciona con la mayoría de los sistemas de archivos basados ​​en disco modernos, muy rápido:

Por ejemplo:

fallocate -l 10G gentoo_root.img
Franta
fuente
55
¿Es posible que dd ya lo esté usando internamente? Si hago 'dd if = / dev / zero of = zerofile bs = 1G count = 1' en un kernel 3.0.0, la escritura termina en 2 segundos, con una velocidad de datos de escritura de más de 500 megabytes por segundo. Eso es claramente imposible en un disco duro portátil de 2.5 ".
lxgr
21
fallocatees exactamente lo que estaba buscando
AB
77
Esto ( fallocate) tampoco funcionará en un sistema de archivos ZFS de Linux - github.com/zfsonlinux/zfs/issues/326
Joe
55
Falocate tampoco es compatible con ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
En Debian, GNU / Linux fallocatees parte del util-linuxpaquete. Esta herramienta fue escrita por Karel Zak de RedHat y el código fuente se puede encontrar aquí: kernel.org/pub/linux/utils/util-linux
Franta
295

Esta es una pregunta común, especialmente en el entorno actual de entornos virtuales. Desafortunadamente, la respuesta no es tan directa como se podría suponer.

dd es la primera opción obvia, pero dd es esencialmente una copia y eso te obliga a escribir cada bloque de datos (por lo tanto, inicializando el contenido del archivo) ... Y esa inicialización es lo que ocupa tanto tiempo de E / S. (¿Quiere que se demore aún más? ¡Use / dev / random en lugar de / dev / zero ! ¡Entonces usará la CPU y el tiempo de E / S!) Sin embargo, al final, dd es una mala elección (aunque esencialmente predeterminado utilizado por la VM "crear" GUI). P.ej:

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

truncar es otra opción, y es probable que sea la más rápida ... Pero eso se debe a que crea un "archivo disperso". Esencialmente, un archivo disperso es una sección del disco que tiene muchos de los mismos datos, y el sistema de archivos subyacente "engaña" al no almacenar realmente todos los datos, sino simplemente "pretender" que todo está allí. Por lo tanto, cuando usa truncar para crear una unidad de 20 GB para su VM, el sistema de archivos en realidad no asigna 20 GB, pero hace trampa y dice que hay 20 GB de ceros allí, a pesar de que solo hay una pista en el disco en realidad puede (realmente) estar en uso. P.ej:

 truncate -s 10G gentoo_root.img

fallocate es el final - y mejor - elección para su uso con asignación de disco VM, porque es esencialmente "reservas" (o "asigna" todo el espacio que usted está buscando, pero no se molestan en escribir nada lo tanto,. cuando usa Falocate para crear un espacio de disco virtual de 20 GB, realmente obtiene un archivo de 20 GB (no un "archivo disperso", y no se habrá molestado en escribirle nada, lo que significa que prácticamente cualquier cosa podría estar en allí, ¡como un disco nuevo!) Por ejemplo:

fallocate -l 10G gentoo_root.img
Dan McAllister
fuente
44
+1 truncatees funcional en JFS; fallocate, no tanto. Un punto: no puede incluir un decimal en el número, necesitaba especificar 1536G, no 1.5T.
Calrion
1
De acuerdo a mi fallocatepágina de manual, esto sólo es compatible con btrfs, ext4, ocfs2, y xfssistemas de archivos
Nathan S. Watson-Haigh
Nota swapondesafortunadamente no funciona en extensiones preasignadas, la última vez que lo verifiqué. Se discutió en la lista de correo XFS acerca de tener una opción de Fallocate para exponer los viejos datos de espacio libre y no tener la extensión marcada como preasignada, por lo que swapon funcionaría. Pero no creo que se haya hecho nada.
Peter Cordes
1
Para su información, tratar de leer demasiados datos /dev/randompuede resultar en que se agoten los datos aleatorios, y "Cuando el grupo de entropía está vacío, las lecturas de / dev / random se bloquearán hasta que se acumule ruido ambiental adicional", por lo que podría tomar muy, muy muy mucho tiempo
Xen2050
154

Linux y todos los sistemas de archivos

xfs_mkfile 10240m 10Gigfile

Linux y algunos sistemas de archivos (ext4, xfs, btrfs y ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS y probablemente otros UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Explicación

Pruebe mkfile <size>myfile como alternativa de dd. Con la -nopción se indica el tamaño, pero los bloques de disco no se asignan hasta que se escriben datos en ellos. Sin la -nopción, el espacio está lleno de cero, lo que significa escribir en el disco, lo que significa tomar tiempo.

mkfile se deriva de SunOS y no está disponible en todas partes. La mayoría de los sistemas Linux tienen lo xfs_mkfileque funciona exactamente de la misma manera, y no solo en los sistemas de archivos XFS a pesar del nombre. Se incluye en xfsprogs (para Debian / Ubuntu) o paquetes con nombre similares.

La mayoría de los sistemas Linux también tienen fallocate, que solo funciona en ciertos sistemas de archivos (como btrfs, ext4, ocfs2 y xfs), pero es el más rápido, ya que asigna todo el espacio de archivos (crea archivos que no son holey) pero no inicializa ninguno de eso.

CMS
fuente
55
¿Dónde está este archivo mk del que hablas, extraño? No está en la instalación predeterminada de RHEL.
paxdiablo
2
Es una utilidad solaris. si busca gpl mkfile, encontrará algunos ejemplos de código fuente.
Martin Beckett el
55
Funciona como un encanto en OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfileestá incluido en xfsprogs en Ubuntu y funciona de maravilla en mi ext3 fs. :)
Greg Dubicki
97
truncate -s 10M output.file

creará un archivo de 10 M instantáneamente (M significa 1024 * 1024 bytes, MB significa 1000 * 1000 - lo mismo con K, KB, G, GB ...)

EDITAR: como muchos han señalado, esto no asignará físicamente el archivo en su dispositivo. Con esto, podría crear un archivo grande arbitrario, independientemente del espacio disponible en el dispositivo, ya que crea un archivo "disperso".

Entonces, al hacer esto, diferirá la asignación física hasta que se acceda al archivo. Si está asignando este archivo a la memoria, es posible que no tenga el rendimiento esperado.

Pero este sigue siendo un comando útil para saber

kiv
fuente
1
Intenté esto, pero no afecta el espacio disponible en disco. Debe porque es un archivo disperso como se describió anteriormente.
Gringo Suave
77
Esta no debería ser la respuesta principal, ya que no resuelve el problema, la fallocaterespuesta a continuación sí lo hace.
Gringo Suave
44
@GringoSuave, pero esto sigue siendo útil para algunas personas que pueden tener un problema similar pero ligeramente diferente.
AJMansfield
@GringoSuave: Parece crear un archivo grande según lo solicitado, ¿por qué no resuelve el problema? También hay notas debajo de la respuesta de Falocate que ni siquiera funciona en la mayoría de los casos.
Pavel Šimerda
1
¿Por qué sugerir hacer archivos dispersos cuando dijo que eso no funcionará?
hpavc
44

Donde search es el tamaño del archivo que desea en bytes - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Zoredache
fuente
66
Me gusta este enfoque, pero el comentarista no quiere un archivo escaso por alguna razón. :(
ephemient
3
dd if = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien
77
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret el
1
Para archivos dispersos, truncateparece ser mucho mejor.
Pavel Šimerda
36

Ejemplos donde search es el tamaño del archivo que desea en 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


Desde la página de manual de dd:

Los BLOQUES y BYTES pueden ir seguidos de los siguientes sufijos 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, y así sucesivamente para T, P, E, Z, Y.

Sepero
fuente
Esto se ve mucho mejor que la forma n-1 , por lo que es básicamente equivalente a truncate.
Pavel Šimerda
19

Para hacer un archivo de 1 GB:

dd if=/dev/zero of=filename bs=1G count=1
max
fuente
77
Creo que el recuento debe ser 1. (probado en centos)
SvennD
dd if=/dev/zero of=filename bs=20G count=1¡solo creará un archivo de 2GB! no 20GB.
Maulik Gangani
18

No sé mucho sobre Linux, pero aquí está el código C que escribí para falsificar archivos enormes en DC Share hace muchos años.

#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 Humungo
fuente
debe haber mejores enfoques en C. También debe cerrar el archivo. Iterando a un millón escribiendo 1 char a la vez ...
ACV
10

También puede usar el comando "sí". La sintaxis es bastante simple:

#yes >> myfile

Presiona "Ctrl + C" para detener esto, de lo contrario se comerá todo tu espacio disponible.

Para limpiar este archivo, ejecute:

#>myfile

limpiará este archivo.

Yogui
fuente
7

No creo que vaya a ser mucho más rápido que dd. El cuello de botella es el disco; escribir cientos de GB de datos en él llevará mucho tiempo sin importar cómo lo haga.

Pero aquí hay una posibilidad que podría funcionar para su aplicación. Si no le importa el contenido del archivo, ¿qué le parece crear un archivo "virtual" cuyo contenido sea la salida dinámica de un programa? En lugar de abrir () el archivo, use popen () para abrir una tubería a un programa externo. El programa externo genera datos cuando sea necesario. Una vez que la tubería está abierta, actúa como un archivo normal en el sentido de que el programa que abrió la tubería puede fseek (), rewind (), etc. Deberá usar pclose () en lugar de close () cuando esté hecho con la pipa.

Si su aplicación necesita que el archivo tenga un tamaño determinado, dependerá del programa externo realizar un seguimiento de dónde se encuentra el "archivo" y enviar un eof cuando se haya alcanzado el "final".

Barry Brown
fuente
4

Un enfoque: si puede garantizar que las aplicaciones no relacionadas no utilizarán los archivos de manera conflictiva, simplemente cree un grupo de archivos de diferentes tamaños en un directorio específico, luego cree enlaces a ellos cuando sea necesario.

Por ejemplo, tenga un grupo de archivos llamado:

  • / inicio / archivos grandes / 512M-A
  • / inicio / archivos grandes / 512M-B
  • / inicio / archivos grandes / 1024M-A
  • / inicio / archivos grandes / 1024M-B

Luego, si tiene una aplicación que necesita un archivo 1G llamado / home / oracle / logfile, ejecute un " ln /home/bigfiles/1024M-A /home/oracle/logfile".

Si está en un sistema de archivos separado, deberá usar un enlace simbólico.

Los archivos A / B / etc. se pueden usar para garantizar que no haya un uso conflictivo entre aplicaciones no relacionadas.

La operación de enlace es lo más rápida posible.

paxdiablo
fuente
Puede tener una piscina pequeña o una piscina grande, es su elección. Necesitarías al menos un archivo de todos modos, ya que eso es lo que pidió el interrogador. Si su grupo consta de un archivo, no pierde nada. Si tiene cargas de disco (y debería, dado su bajo precio), no hay problema.
paxdiablo
3

El archivo GPL mk es solo un contenedor de script (ba) sh alrededor de dd; El archivo mk de BSD solo establece un búfer con un valor distinto de cero y lo escribe repetidamente. No esperaría que el primero superara a dd. Este último puede superar dd if = / dev / zero ligeramente ya que omite las lecturas, pero cualquier cosa que lo haga significativamente mejor probablemente solo esté creando un archivo disperso.

En ausencia de una llamada al sistema que realmente asigne espacio para un archivo sin escribir datos (y Linux y BSD carecen de esto, probablemente también Solaris), puede obtener una pequeña mejora en el rendimiento al usar ftrunc (2) / truncate (1) para extender el archivo al tamaño deseado, mmap el archivo en la memoria, luego escriba datos distintos de cero en los primeros bytes de cada bloque de disco (use fgetconf para encontrar el tamaño del bloque de disco).

Alex Dupuy
fuente
44
BSD y Linux tienen Falocate en realidad (editar: ahora es POSIX y está ampliamente disponible).
Tobu
3

Plug descarado: OTFFS proporciona un sistema de archivos que proporciona archivos arbitrariamente grandes (bueno, casi. Exabytes es el límite actual) de contenido generado. Es solo para Linux, C simple y en alfa temprano.

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

stefan
fuente
3

Esto es lo más rápido que podría hacer (que no es rápido) con las siguientes restricciones:

  • El objetivo del archivo grande es llenar un disco, por lo que no puede ser comprimible.
  • Usando el sistema de archivos ext3. ( fallocateno disponible)

Esta es la esencia de esto ...

// 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);
}

En nuestro caso, esto es para un sistema Linux integrado y funciona bastante bien, pero preferiría algo más rápido.

FYI, el comando dd if=/dev/urandom of=outputfile bs=1024 count = XXfue tan lento que no se pudo utilizar.

user79878
fuente