ejemplos - crear archivo grande linux
Crea rĂ¡pidamente un archivo grande en un sistema Linux (14)
¿Cómo puedo crear rápidamente un archivo grande en un sistema Linux ( Red Hat Linux )?
dd hará el trabajo, pero leer /dev/zero
y escribir en la unidad puede llevar mucho tiempo cuando necesite un archivo de varios cientos de GB de tamaño para realizar pruebas ... Si necesita hacerlo repetidamente, el tiempo realmente suma.
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 asigne espacio en disco al archivo.
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 UNIXes
mkfile 10240m 10Gigfile
HP-UX
prealloc 10Gigfile 10737418240
Explicación
Pruebe mkfile <size>
myfile como una alternativa de dd
. Con la opción -n
se anota el tamaño, pero los bloques de disco no se asignan hasta que se escriben los datos. Sin la opción -n
, el espacio se llena con 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 un xfs_mkfile
que 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 nombres 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 no holey) pero no se inicializa cualquiera de eso.
Donde buscar es el tamaño del archivo que desea en bytes - 1.
dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Ejemplos donde buscar 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 del manual de dd:
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.
El archivo mk GPL es solo un (ba) sh script wrapper alrededor de dd; El archivo mk de BSD se limita a un búfer con un valor distinto de cero y lo escribe repetidamente. No esperaría que el primero superara a dd. El último podría eliminar dd if = / dev / zero ligeramente ya que omite las lecturas, pero cualquier cosa que lo haga significativamente mejor es probablemente crear un archivo disperso.
Sin una llamada al sistema que realmente asigna espacio para un archivo sin escribir datos (y Linux y BSD carecen de esto, probablemente Solaris también), es posible que obtenga una pequeña mejora en el rendimiento al utilizar ftrunc (2) / truncate (1) para extender el archivo. al tamaño deseado, haga un mapa del archivo en la memoria, luego escriba datos que no sean cero en los primeros bytes de cada bloque de disco (use fgetconf para encontrar el tamaño del bloque de disco).
Enchufe desvergonzado: 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 temprana.
Consulte https://github.com/s5k6/otffs .
Esta es una pregunta común, especialmente en el entorno actual de los entornos virtuales. Desafortunadamente, la respuesta no es tan sencilla 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 toma tanto tiempo de E / S. (¿Quiere que se demore más? ¡Use /dev/random lugar de /dev/zero ! ¡Luego usará la CPU y el tiempo de E / S!) Sin embargo, al final, dd es una mala elección (aunque esencialmente es predeterminado utilizado por la VM "crear" GUIs). P.ej:
dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G
truncate es otra opción, y es probablemente 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 "simular" que todo está allí. Por lo tanto, cuando utiliza Truncate para crear una unidad de 20 GB para su máquina virtual, el sistema de archivos no asigna realmente 20 GB, pero hace trampa y dice que hay 20 GB de ceros, aunque solo sea una pista en el disco. en realidad puede (realmente) estar en uso. P.ej:
truncate -s 10G gentoo_root.img
fallocate es la opción final, y la mejor , para usar con la asignación de discos VM, porque esencialmente "reserva" (o "asigna" todo el espacio que está buscando, pero no se molesta en escribir nada). cuando utiliza fallocate 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 una especie de disco nuevo!) Por ejemplo:
fallocate -l 10G gentoo_root.img
Esto es lo más rápido que pude hacer (que no es rápido) con las siguientes restricciones:
- El objetivo del archivo grande es llenar un disco, por lo que no se puede comprimir.
- Utilizando el sistema de archivos ext3. (no 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 esto funciona lo suficientemente bien, pero preferiría algo más rápido.
Para su información, el comando "dd if = / dev / urandom of = outputfile bs = 1024 count = XX" era tan lento que no se podía usar.
No creo que vayas 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 canalización a un programa externo. El programa externo genera datos siempre que sea necesario. Una vez que la tubería está abierta, actúa como un archivo normal, ya que el programa que abrió la tubería puede sonar (), rebobinar (), etc. Necesitará usar pclose () en lugar de cerrar () cuando esté hecho con el tubo.
Si su aplicación necesita que el archivo tenga un tamaño determinado, dependerá del programa externo hacer un seguimiento de dónde se encuentra en el "archivo" y enviar un eof cuando se llegue al "final".
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");
}
}
Para hacer un archivo de 1 GB:
dd if=/dev/zero of=filename bs=1G count=1
Puedes usar el comando "sí" también. La sintaxis es bastante simple:
#yes >> myfile
Presiona "Ctrl + C" para detener esto, de lo contrario, consumirá todo el espacio disponible.
Para limpiar este archivo ejecute:
#>myfile
limpiará este archivo.
Un enfoque: si puede garantizar que las aplicaciones no relacionadas no utilizarán los archivos de manera conflictiva, simplemente cree un conjunto de archivos de diferentes tamaños en un directorio específico, luego cree enlaces a ellos cuando sea necesario.
Por ejemplo, tener un conjunto de archivos llamados:
- / home / bigfiles / 512M-A
- / Inicio / Bigfiles / 512M-B
- / home / bigfiles / 1024M-A
- / home / bigfiles / 1024M-B
Luego, si tiene una aplicación que necesita un archivo 1G llamado / home / oracle / logfile, ejecute " ln /home/bigfiles/1024M-A /home/oracle/logfile
".
Si está en un sistema de archivos separado, tendrá que usar un enlace simbólico.
Los archivos A / B / etc pueden usarse para asegurar que no haya un uso conflictivo entre aplicaciones no relacionadas.
La operación de enlace es lo más rápido que puede obtener.
dd
es una buena solución, pero es lenta para este propósito. En Linux, tenemos fallocate
.
Por ejemplo:
fallocate -l 10G gentoo_root.img
truncate -s 10M output.file
creará un archivo 10 M de forma instantánea (M significa 1024 * 1024 bytes, MB significa 1000 * 1000, igual que K, KB, G, GB ...)
EDITAR: como muchos han señalado, esto no asignará físicamente el archivo en su dispositivo. Con esto, realmente podría crear un archivo grande arbitrario, independientemente del espacio disponible en el dispositivo
Por lo tanto, al hacer esto, estará aplazando 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.