Rellenar un archivo con ceros

12

Su tarea hoy será tomar un archivo existente y agregarle ceros hasta que alcance un cierto tamaño.

Debe escribir un programa o función que tome el nombre de un archivo en el directorio actual fy una cantidad de bytes b. Mientras mantiene el contenido original de f, debe escribir ceros (bytes nulos, no ascii 0s) hasta el final para que su nuevo tamaño sea bbytes.

Puede suponer que fsolo tiene ascii alfanumérico en su nombre, que tiene permisos completos sobre él, que inicialmente no es mayor que b, pero puede ser tan grande como b, y que hay un espacio libre infinito en el disco.

No puede suponer que no festá vacío o que no contiene bytes nulos.

Otros archivos existentes no deberían modificarse y los archivos nuevos no deberían existir después de que finalice la ejecución.

Casos de prueba

Contenido de f | b | Contenido resultante de f
12345 | 10 | 1234500000
0 | 3 | 000
[vacío] | 2 | 00
[vacío] | 0 | [vacío]
123 | 3 | 123
Pavel
fuente
@totallyhuman inicialmente no es más grande queb
Adám
¿Podemos tomar el contenido del archivo como entrada y salida del contenido modificado?
Shaggy
¿Podemos usar bibliotecas?
Adám
1
@ Phoenix El problema es que Dennis colocó la biblioteca en una carpeta lejana (no es mi elección). ¿Puedo contar como si estuviera disponible en la ruta de búsqueda?
Adám
¿Podemos suponer que el archivo no contendrá bytes nulos?
Dom Hastings

Respuestas:

20

Bash + coreutils, 13

truncate -s$@

Entrada desde la línea de comandos: el primer parámetro es el tamaño del archivo y el segundo es el nombre del archivo.

De man truncate:

Si un ARCHIVO es más corto, se extiende y la parte extendida (agujero) se lee como cero bytes.

Pruébalo en línea .

Trauma digital
fuente
1
¿Puede truncar extender también?
Adám
11
Un hombre que conoce a su hombre en un hombre varonil.
Magic Octopus Urn
Me pregunto si funciona en una partición FAT, donde truncatefalla la llamada al sistema.
Matteo Italia
1
Mi implementación de la misma idea habría sido dd bs=1 of=$1 seek=$2<&-(que imprime un mensaje de error que puede ignorarse). El tuyo es mucho más corto. Agradable.
hvd
@hvd sí, pensé que dd probablemente podría hacer esto
Digital Trauma
4

Groovy, 54 47 43 41 bytes

{a,b->(c=new File(a))<<'\0'*(b-c.size())}

-6 gracias a la idea de manatwork de eliminar el bucle; esa fue mi idea original, no sé por qué pensé que no funcionaría y opté por un bucle ... Definitivamente funciona, solo lo probé.

Sin golf:

{
    a,b->                    // Two inputs: a is the File name, b is the desired size.
    File c = new File(a)     // Make and store the file.
    c << '\0'*(b-c.size())   // Append the difference between b and c.size() in nullbytes.
}
                             // Usually a close would be required, but, in Groovy,
                             // because private data isn't so protected, if a File
                             // Object goes out of scope, the attached Stream is 
                             // automatically flushed to disk.
Urna de pulpo mágico
fuente
1
¿No sería más corto sin bucle? {a,b->c=new File(a);c<<('\0'*(b-c.size()))}
manatwork
@manatwork sí! Y en realidad puede ser incluso mejor que eso.
Magic Octopus Urn
@manatwork no importa, el mismo bytecount (c=new File(a))debido al paréntesis requerido.
Magic Octopus Urn
1
No tengo idea de por qué pongo paréntesis alrededor del valor completo para agregar. Innecesario.
manatwork
@manatwork Groovy es bastante temperamental sobre el paréntesis, no puedo culparte jaja.
Magic Octopus Urn
3

Python 2 , 59 57 54 bytes

-5 bytes gracias a chepner

def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b)
varilla
fuente
1
@totallyhuman \x00es un byte nulo.
Pavel
1
@totallyhuman no, es más como una cosa de bandera (no permitir interactino con archivos cerrados)
Rod
1
@ Rod ¡Me encanta interactino! El mejor juego interactivo para
niños
Se puede usar \0en lugar de \x00.
chepner
Puede guardar otros tres bytes por extensión excesiva, entonces truncando: def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b).
chepner
3

PHP, 66 bytes

for($p=fopen($f=$argv[1],a);filesize($f)<$argv[2];)fputs($p,"\0");

Toma información de los argumentos de la línea de comando; correr con -nr.


Estos 55 bytes podrían, pero probablemente no funcionarán:

fseek($p=fopen($argv[1],"w+"),$argv[2]);fputs($p,"\0");
Titus
fuente
2

Java (Oracle JRE), 55 bytes

f->b->new java.io.RandomAccessFile(f,"rw").setLength(b)

La especificación de setLength(int)dice que los bytes agregados no están definidos, pero prácticamente Oracle JRE agrega solo el 0byte (es por eso que lo especifiqué).

La JVM cierra automáticamente el recurso, por lo que no necesitamos hacerlo nosotros mismos.

Prueba

public class Pcg125661 {
  interface F {
    B f(String f);
  }
  interface B {
    void b(int b) throws java.io.IOException;
  }
  public static void main(String[] args) throws java.io.IOException {
    F a = f->b->new java.io.RandomAccessFile(f,"rw").setLength(b);
    a.f("a").b(100);
  }
}
Olivier Grégoire
fuente
1

AHK, 48 bytes

FileGetSize,s,%1%
2-=s
Loop,%2%
FileAppend,0,%1%

1y 2son los primeros dos parámetros en un script AHK.
FileGetSizefunciona en bytes por defecto.
No es emocionante, pero es simple: obtenga el tamaño, reste el tamaño deseado y agregue tantos ceros.

Tostadas de ingeniero
fuente
1

Perl 6 , 40 bytes

{$_=$^a.IO;.open(:a).put("\0"x($^b-.s))}

$^ay $^bson los parámetros de la función: el nombre del archivo y la longitud, respectivamente.

Sean
fuente
1

Python 2 , 68 bytes

def g(f,b):
 with open(f,'r+')as c:c.write('\x00'*(b-len(c.read())))

Pruébalo en línea! (Al imprimir el contenido del archivo, el código reemplaza los bytes nulos con 0 ASCII para mayor visibilidad).

totalmente humano
fuente
1
Creo que esto escribe ceros ASCII y no bytes nulos
Pavel
Ah ... la palabra ceros era engañosa ...
totalmente humana
Bueno, sí dice en letras grandes en el desafío en sí.
Pavel
¿Puedes usar un literal \ x00 en la cadena (no una secuencia de escape)?
CalculatorFeline
2
No puede usar un byte nulo literal, pero \0es más corto.
xnor
1

PowerShell, 69 bytes

param($f,$s)@(gc $f -en by)+,[byte]0*($s-(gi $f).length)|sc $f -en by
#     ^ filename
#        ^desired size
#                 ^ get content as byte stream
#           ^force it to an array even if there's 0 or 1 byte
#                          ^append a byte array of nulls..
#                                       ^..desired size - file size
#                            write to file with -encoding byte ^

$fpara el archivo, $spara el tamaño de destino, guárdelo como .ps1 y ejecute

.\Add-NullBytesToFile.ps1 .\test.txt 10

Es un shell, por lo que debería haber un bucle realmente pequeño que agregue 1 byte con >>redirección de salida y anexar, ¿verdad? Bueno, no, porque >>solo genera la codificación multibyte UCS2-LE, por lo que no hay forma de agregar un solo byte a un archivo con él ... a menos que esté usando PSv5.1 y pueda cambiar eso, pero eso hace que sea demasiado largo para ser competitivo :

$PSDefaultParameterValues['Out-File:Encoding']='utf8';while((gi $f).length-lt$c){[byte]0>>$f}

¿Quizás haya un enfoque de .Net Framework? Debería haberlo, pero no puedo hacer que realmente escriba ningún byte o error. Pero es más largo de todos modos:

param($f,$s)[io.file]::WriteAllBytes($f,[byte[]](,0)*($c-(gi $f).length), $True)
TessellatingHeckler
fuente
1

Mathematica 50 Bytes

Importación y exportación

Export[#,Import[#,c="Byte"]~Join~Table[0,{#2}],c]&

Uso

%["test1", 5]
Kelly Lowder
fuente
1

q, 29 bytes

Función que toma el nombre del archivo en formato :/foo/bar.bazy longitud como un entero.

{hopen[x](0|y-hcount x)#0x00}

Ejemplo:

{hopen[x](0|y-hcount x)#0x00}[`:test.txt;100]
skeevey
fuente
1

C, 56 bytes

fseek(f,0,2);int i;for(;ftell(f)<b;)putc(0,f);fclose(f);

El programa encuentra el tamaño del archivo y cuántos bytes agregar. El archivo agrega fs - bbytes adicionales al final.

Garhoogin
fuente
1
Bienvenido a PPCG! Este es un desafío de código de golf , por lo que su objetivo es hacer que su programa sea lo más pequeño posible. Debería comenzar eliminando espacios en blanco innecesarios.
Pavel
44
Además, su programa parece asumir que las entradas ya están almacenadas en los valores fy b, lo que no está permitido. Usted debe incluir i / o en su programa, que puede ser desde ARGV, entrada de la consola, o argumentos a una función.
Pavel
Gracias, pensé que se suponía que las variables ya estaban establecidas. Culpa mía.
Garhoogin
1

C #, 90 bytes

using System.IO;s=>n=>File.AppendAllText(s,new string('\0',(int)new FileInfo(s).Length-n))
TheLethalCoder
fuente