¿Cómo agrego un número específico de bytes nulos a un archivo? [cerrado]

26

Tengo un script que escribe en algunos archivos pero los necesito de un tamaño específico. Entonces, me pregunto si hay una manera de agregar un número específico de bytes nulos a un archivo utilizando herramientas de línea de comando estándar (por ejemplo, copiando desde /dev/zero).

incógnito2
fuente
1
Esta pregunta parece estar fuera de tema porque se trata de la programación, que pertenece a Stack Overflow .
Jenny D dice Reinstate Monica el
¿ oflag=appendFunciona para ti?
Mark K Cowan
Para aclarar un comentario de @ Mark K Cowan; se refiere al ddcomando.
Alexander Pozdneev
FYI parece que fallocatees otra opción para insertar agujeros en un archivo. superuser.com/a/1172904/111432
akostadinov

Respuestas:

41

truncatees mucho más rápido que dd. Para hacer crecer el archivo con 10 bytes, use:

 truncate -s +10 file.txt 
Piedra
fuente
2
Es mucho más rápido porque generará un archivo disperso, que es lo que desea la mayor parte del tiempo, pero si no desea un archivo disperso, el enfoque dd funcionará.
derobert
34

Puedes probar esto también

dd if=/dev/zero bs=1 count=NUMBER >> yourfile

Esto leerá desde / dev / zero y se agregará a su número de bytes NÚMERO.

Can Kavaklıoğlu
fuente
7

A continuación se muestra un ejemplo de agregar 10MB a un archivo usando solo dd.

[root@rhel ~]# cp /etc/motd ./test
[root@rhel ~]# hexdump -C test |tail -5
000003e0  0a 0a 3d 3d 3d 3d 3e 20  54 65 78 74 20 6f 66 20  |..====> Text of |
000003f0  74 68 69 73 20 6d 65 73  73 61 67 65 20 69 73 20  |this message is |
00000400  69 6e 20 2f 65 74 63 2f  6d 6f 74 64 20 3c 3d 3d  |in /etc/motd <==|
00000410  3d 3d 0a                                          |==.|
00000413

[root@rhel ~]# dd if=/dev/zero of=/root/test ibs=1M count=10 obs=1M oflag=append conv=notrunc
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.0208541 s, 503 MB/s

[root@rhel ~]# hexdump -C test |tail -5
00000410  3d 3d 0a 00 00 00 00 00  00 00 00 00 00 00 00 00  |==..............|
00000420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00a00410  00 00 00                                          |...|
00a00413
Andrey Arapov
fuente
5

mi primera suposición sería:

dd if=/dev/zero of=myfile bs=1 count=nb_of_bytes seek=$(stat -c%s myfile)

Básicamente, este comando le dice a dd que "vaya" al final del archivo y agregue algunos bytes previamente leídos de / dev / zero.

Saludos,

Jeremy
fuente
2
cat "your file" /dev/zero | head -c "total number of bytes"

o

head -c "number of bytes to add" /dev/zero >> "your_file"

y para calcular el tamaño más fácilmente:

head -c $(( "total number of bytes" - $(stat -c "%s" "your_file") )) /dev/zero >> "your_file"
jfg956
fuente
0

Si está rellenando su archivo con bytes nulos, supongo que está manipulando el archivo en a char *en C. Si este es el caso, es posible que no necesite rellenar el archivo con bytes nulos, solo agregando un byte nulo al final del archivo y luego rellenarlo con bytes aleatorios podría ser suficiente. En este caso, el siguiente programa C sería muy eficiente (para usarse solo en archivos más pequeños que el segundo parámetro; de lo contrario, los datos se sobrescribirán). Incluso podría hacer lo que quiera (relleno con bytes nulos) ya que la lseekdefinición de la función establece que:

La función lseek () permitirá que el desplazamiento del archivo se establezca más allá del final de los datos existentes en el archivo. Si los datos se escriben más tarde en este punto, las lecturas subsiguientes de datos en el intervalo devolverán bytes con el valor 0 hasta que los datos se escriban realmente en el intervalo.

En este caso, la primera llamada a lseeky writepodría eliminarse. Pero las pruebas deben hacerse en su sistema primero ...

#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

/* 1st parameter: a file name, 2nd parameter: a file size. */
int main(int argc, char ** args) {
   int nfd = open(args[1], O_WRONLY);
   lseek(nfd, 0, SEEK_END);
   write(nfd, "\0", 1);
   lseek(nfd, atoi(args[2]) - 1, SEEK_SET);
   write(nfd, "\0", 1);
   close(nfd);
   return 0;
}
jfg956
fuente