Comprobar un archivo contiene solo bytes nulos


12

Su objetivo es escribir un programa o función que tome como entrada una cadena que represente la ruta a un archivo, y genere un valor verdadero si ese archivo no está vacío y no contiene bytes no nulos, es decir, todos los bits son 0 - - y un valor falsey de lo contrario.

Me doy cuenta de que es un problema muy simple y creo que podría hackear algo, pero sospecho que debe haber una forma corta y elegante de hacerlo, y eso me dio la idea de desafiarlo.

Este es el , por lo que gana el código más corto en bytes. (Mi preferencia iría a la solución más rápida, pero eso depende demasiado de la implementación ...)

Preguntas relacionadas : Rellene un archivo con ceros

Motivación : Esto es solo para saber de dónde viene el problema, en caso de que esté interesado. No necesitas leerlo.

Las imágenes ISO de CD y DVD, copiadas con "dd" u otros medios, a menudo terminan con una secuencia de bloques inútiles que contienen solo bytes nulos. Las técnicas estándar para eliminar estos bloques son conocidas y simples (consulte /unix/74827/ ) pero a veces pueden eliminar datos útiles no nulos porque el medio puede mentir sobre su propio tamaño. Por lo tanto, quiero verificar que los bloques eliminados contengan solo bytes nulos. Eliminar estos bloques es importante para definir una versión normalizada de imágenes ISO.

Respuestas:


5

Pyth, 6 5 bytes

!sCM'

Pruébalo en línea!

Toma un nombre de archivo de STDIN, abre y lee el archivo, lo convierte en una lista de ints (piense en Python ord) sums la lista (devolverá 0si el archivo es todos bytes nulos), y nots el resultado, imprimiéndolo.


Oye,

Esto se parece mucho a una pregunta de programación general. Estos pertenecen a Stack Overflow . Sin embargo, a partir de los comentarios en la publicación principal, puedo ver que esta no fue su intención. Dicho esto, siento que la discusión ha sido innecesariamente hostil en ambos lados, ¡así que he decidido tomar el relevo y darle la bienvenida PPCG adecuada!

En general, pedimos que los desafíos se publiquen primero en nuestro entorno limitado para recibir comentarios adecuados. Puede echar un vistazo a las presentaciones actuales allí para ver qué formato preferimos para los desafíos. ¡Inténtalo la próxima vez!

Por si acaso todos hemos entendido mal y le estamos buscando una solución general, he aquí una solución en Python 3:

def main(string):
    with open(string) as file:
        return not any(map(ord,file.read()))

1
Esto no funcionará con una imagen en escala de grises que consista solo en píxeles negros (ceros), debido a lo poderosa que 'es.
user202729

Además: OP requiere tomar el nombre del archivo como entrada utilizando el argumento de la línea de comandos y devolverlo como código de estado.
user202729

2

GNU sed -zn , 5 bytes

El archivo de entrada se pasa a sed como un parámetro de línea de comandos. Salida como un código de retorno de shell estándar, es decir, 0 es VERDADERO, 1 es FALSO.

/./q1

Normalmente sedfunciona en registros de entrada delimitados por nueva línea ("líneas" AKA). -zcambia esto a registros de entrada delimitados por nul. Si algún registro de entrada coincide con la .expresión regular, entonces quit con el código de salida 1.

Pruébalo en línea!


2

DOS, 37 bytes


100:BE 80 00 MOV SI, 0080
103:AD       LODSW ;get command-line length
104:98       CBW ;only a byte
105:93       XCHG BX,AX
106:88 40 FF MOV [BX+SI-01], AL ;zero end of name
109:B4 3D    MOV AH, 3D
10B:89 F2    MOV DX, SI
10D:CD 21    INT 21 ;open file
10F:93       XCHG BX, AX ;handle into BX
110:AF       SCASW ;DI=0
111:B4 3F    MOV AH, 3F
113:B1 01    MOV CH, 01
115:CD 21    INT 21 ;read 1 byte
117:91       XCHG CX, AX
118:E3 06    JCXZ 0120 ;quit on EOF
11A:97       XCHG DI, AX ;set true for later
11B:38 2C    CMP [SI], CH
11D:74 F2    JZ 0111 ;loop while zero
11F:4F       DEC DI ;set false
120:97       XCHG DI, AX
121:B4 4C    MOV AH, 4C ;return
123:CD 21    INT 21

Abre el archivo nombrado en la línea de comando, devuelve 0 si está vacío o contiene un valor distinto de cero; de lo contrario, devuelve 1.


1

Adjunto , 24 bytes

Zero@Max&0@Ords@FileRead

Pruébalo en línea!

Explicación

Esta es una composición de 4 funciones, ejecutadas una tras otra:

  • FileRead - toma un nombre de archivo como entrada, devuelve el contenido de ese archivo
  • Ords - devuelve los puntos de código ASCII de cada carácter en una lista
  • Max&0- esto es equivalente a, por argumento x, Max[x, 0]; esto a su vez calcula el máximo de todas las entradas en xy 0(dando lugar 0a la lista vacía)
  • Zero - este es un predicado que verifica si este número es de hecho 0 y devuelve ese booleano.

OP requiere un programa completo, llamar desde la línea de comando, tomar el nombre del archivo como entrada usando un argumento y regresar como código de estado. ( @_@)
user202729

¿No da esto un falso positivo para un archivo vacío?
ngenisis

1
@ngenisis el problema original decía lo siguiente: "Eso significa que el archivo vacío se considera correcto" - verifique el historial de revisiones, parece que cierto usuario editó ese punto fuera de la pregunta.
Conor O'Brien

1

C (plataforma de 32 bits), 65 bytes

main(x,v)int*v;{for(v=fopen(v[1],"r");!(x=fgetc(v)););return++x;}

Asume que los tamaños de los punteros son todos iguales, lo cual es casi siempre cierto. Regresa con un 0código de salida en caso de éxito (el archivo contiene solo NULcaracteres), algún otro valor de lo contrario.

El comportamiento no está definido si el argumento de la línea de comando no es una ruta a un archivo legible.


Creo que necesitas escribir int**v? No puedo encontrar un compilador donde esto no sea predeterminado sin hacerlo. Además, puede ahorrar un poco por error intencional , pero no sé si este es el mejor enfoque.
FryAmTheEggman

¿Eh? Intenté esto con gcc en mingw32, funciona perfectamente. Probablemente debería agregar la restricción sizeof(void*) == sizeof(int)(o más generalmente "plataforma de 32 bits") entonces ... en una amd64plataforma, intente compilar con -m32;)
Felix Palmen

@FryAmTheEggman también funciona en TIO cuando se compila como código de 32 bits ( -m32): ¡ Pruébelo en línea!
Felix Palmen

Ah, por supuesto. ¡Buen trabajo, entonces! Siéntase libre de usar mi sugerencia para guardar el par de bytes :)
FryAmTheEggman

0

Bash + utilidades GNU, 26 bytes

od -An $1|grep -qv [^0\ *]

El nombre de archivo de entrada se proporciona como un parámetro de línea de comandos. Salida como un código de retorno de shell estándar, es decir, 0 es VERDADERO, 1 es FALSO.

Pruébalo en línea!


0

Wolfram Language (Mathematica) , 30 bytes

BinaryReadList@#~MatchQ~{0..}&

Pruébalo en línea!

Explicación

                             & (* Function which returns whether *)
BinaryReadList                 (* the list of bytes *)
              @                (* of *)
               #               (* the input *)
                ~MatchQ~       (* matches *)
                        {0..}  (* a list of a one or more zeros *)

Solución alternativa, 22 bytes.

Si se supone que pasan los archivos vacíos, esto se puede acortar a:

Tr@BinaryReadList@#<1&

Pruébalo en línea!


0

Java, 149 bytes

boolean b(String f)throws Exception{java.io.InputStream s=new java.io.FileInputStream(f);int i=Math.abs(s.read());while(i==0)i+=s.read();return i<0;}

0

Perl 5, 20 bytes

$\=0;exit<>=~/^\0+$/

Toma un nombre de archivo en argumentos de línea de comando y devuelve la respuesta en el código de salida del programa


0

Python 3, 59 bytes

f=lambda s:any(open(s,'rb').read())+not len(open(s).read())

Devuelve 0 para el éxito (todos los bytes cero).

Devuelve 1 por falla (al menos un byte distinto de cero o archivo de longitud cero).


Si el archivo está vacío, debe devolver Falla.
Adám

0

APL (Dyalog Unicode) , 14 bytes

Programa completo Solicita el nombre de archivo de stdin.

0=⌈/11 ¯1MAP

Pruébalo en línea!

 solicitud de nombre de archivo

11 ¯1⎕MAP asignar ese archivo a una matriz de bits empaquetada

⌈/ máximo (reducción); flotador más pequeño si está vacío, de lo contrario 0 o 1

0= es cero igual a eso?


0

Haskell, 49 bytes

import Data.ByteString
f=(all(<1)<$>).getContents

Obviamente, si la importación no está incluida, entonces es de 26 bytes.


Supongo que quisiste decir en readFilelugar de getContets. Creo que puedes leer el archivo como una cadena normal, compararlo =='\0'(o mejor <'\1') y deshacerte de él import. Como se puede utilizar una función anónima, se puede eliminar el f x=e ir pointfree: (all(<'\1')<$>).readFile.
nimi

Si se trata de un archivo binario, no puede usarlo readFile, lo que arrojará una excepción al encontrar una secuencia Unicode no válida. Buen punto con respecto al punto libre.
Izaak Weiss

0

JavaScript (ES8), 52 bytes

Toma una url como argumento y devuelve una promesa que se resuelve truesi el archivo no está vacío y no contiene bytes nulos.

async p=>!/\0|^$/.test(await(await fetch(p)).text())

0

Zsh , 35 bytes

! for c (${(s::)"$(<$1)"})((i|=#c))

Pruébalo en línea! Salidas a través del código de salida.

Leer, dividir en caracteres y bit a bit, o cada punto de código juntos.

Si el archivo está vacío, el cuerpo del bucle nunca se ejecuta y, por lo tanto, el bucle devuelve la verdad. Si los valores de verdad-falsedad se pueden intercambiar, el inicio !se puede eliminar para guardar 2 bytes.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.