A verificação de um arquivo contém apenas bytes nulos

12

Seu objetivo é escrever um programa ou função que receba como entrada uma string que representa o caminho para um arquivo e emita um valor verdadeiro se esse arquivo não estiver vazio e não contiver bytes não nulos - ou seja, todos os bits são 0 - - e um valor falsey caso contrário.

Percebo que é um problema muito simples e acho que poderia hackear alguma coisa, mas suspeito que deve haver uma maneira curta e elegante de fazer isso, e isso me deu a ideia de desafiá-lo.

Isso é , então o código mais curto em bytes vence. (Minha própria preferência iria para a solução mais rápida, mas isso depende muito da implementação ...)

Questões relacionadas : Proteger um arquivo com zeros

Motivação : é apenas para dizer de onde vem o problema, caso você esteja interessado. Você não precisa lê-lo.

Imagens ISO de CDs e DVDs, copiadas com "dd" ou outros meios, geralmente terminam com uma sequência de blocos inúteis contendo apenas bytes nulos. As técnicas padrão para remover esses blocos são conhecidas e simples (consulte /unix/74827/ ), mas às vezes podem remover dados úteis não nulos porque a mídia pode ter seu próprio tamanho. Então, eu quero verificar se os blocos removidos contêm apenas bytes nulos. A remoção desses blocos é importante para definir uma versão normalizada de imagens ISO.

babou
fonte

Respostas:

5

Pitão, 6 5 bytes

!sCM'

Experimente online!

Pega um nome de arquivo de STDIN, abre e lê o arquivo, converte-o em uma lista de ints (pense em Python ord) sumna lista (retornará 0se o arquivo tiver todos os bytes nulos) e noté o resultado, imprimindo-o.


Ei,

Isso se parece muito com uma questão de programação geral. Eles pertencem ao estouro de pilha . No entanto, pelos comentários no post principal, percebo que essa não era sua intenção. Dito isso, sinto que a discussão foi desnecessariamente hostil de ambos os lados, então decidi pegar a folga e dar as boas-vindas adequadas ao PPCG!

Geralmente, solicitamos que qualquer desafio seja publicado primeiro em nossa caixa de areia para obter um feedback adequado. Você pode dar uma olhada nos envios atuais para ver qual formato preferimos para os desafios. Por favor, tente da próxima vez!

Caso todos nós o tenhamos entendido errado e você esteja procurando uma solução geral, aqui está uma solução no Python 3:

def main(string):
    with open(string) as file:
        return not any(map(ord,file.read()))
hakr14
fonte
1
Isso não funcionará com uma imagem em escala de cinza composta apenas por pixels pretos (zeros), devido à sua potência '.
user202729
Além disso: O OP exige que o nome do arquivo seja inserido como argumento de linha de comando e retorne como código de status.
user202729
2

GNU sed -zn , 5 bytes

O arquivo de entrada é passado para sed como um parâmetro da linha de comandos. Saída como um código de retorno padrão do shell - ou seja, 0 é TRUE, 1 é FALSE.

/./q1

Normalmente sedfunciona em registros de entrada delimitados por nova linha ("linhas" AKA). -zaltera isso para registros de entrada delimitados por nulos. Se algum registro de entrada corresponder ao .regex, quse o código de saída 1.

Experimente online!

Trauma Digital
fonte
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

Ele abre o arquivo nomeado na linha de comando, retorna 0 se vazio ou contém um valor diferente de zero, caso contrário, retorna 1.

Peter Ferrie
fonte
1

Anexo , 24 bytes

Zero@Max&0@Ords@FileRead

Experimente online!

Explicação

Esta é uma composição de 4 funções, executadas uma após a outra:

  • FileRead - pega um nome de arquivo como entrada, retorna o conteúdo desse arquivo
  • Ords - retorna os pontos de código ASCII de cada caractere em uma lista
  • Max&0- isto é equivalente a, por argumento x, Max[x, 0]; por sua vez, calcula o máximo de todas as entradas em xe 0(produzindo 0a lista vazia)
  • Zero - este é um predicado que verifica se esse número é realmente 0 e retorna esse booleano.
Conor O'Brien
fonte
O OP requer um programa completo, chama a partir da linha de comando, toma o nome do arquivo como entrada usando o argumento e retorna como código de status. ( @_@)
user202729
Isso não dá um falso positivo para um arquivo vazio?
Ngenisis
1
@ngenisis, o problema original afirmou o seguinte: "Isso significa que o arquivo vazio é considerado OK" - verifique o histórico de revisões, parece que um determinado usuário editou esse ponto da pergunta.
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;}

Assume que os tamanhos dos ponteiros são iguais, o que quase sempre é verdade. Retorna com um 0código de saída em caso de sucesso (o arquivo contém apenas NULcaracteres), algum outro valor caso contrário.

O comportamento é indefinido se o argumento da linha de comando não for o caminho para um arquivo legível.

Felix Palmen
fonte
Eu acho que você precisa escrever int**v? Não consigo encontrar um compilador em que isso não ocorra sem fazer isso. Além disso, você pode economizar um erro intencionalmente , mas não sei se essa é a melhor abordagem.
FryAmTheEggman
Hã? Eu tentei isso com o gcc no mingw32, funciona perfeitamente. Eu provavelmente deve adicionar a restrição sizeof(void*) == sizeof(int)(ou mais geralmente "plataforma de 32 bits"), então ... em uma amd64plataforma, tentar compilar com -m32;)
Felix Palmen
O @FryAmTheEggman também funciona no TIO quando compilado como código de 32 bits ( -m32): Experimente online!
Felix Palmen
Ah, claro. Bom trabalho, então! Sinta-se livre para usar a minha sugestão para salvar os bytes casal :)
FryAmTheEggman
0

Utilitários Bash + GNU, 26 bytes

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

O nome do arquivo de entrada é fornecido como um parâmetro da linha de comando. Saída como um código de retorno padrão do shell - ou seja, 0 é TRUE, 1 é FALSE.

Experimente online!

Trauma Digital
fonte
0

Wolfram Language (Mathematica) , 30 bytes

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

Experimente online!

Explicação

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

Solução alternativa, 22 bytes

Se arquivos vazios devem passar, isso pode ser reduzido para:

Tr@BinaryReadList@#<1&

Experimente online!

ngenisis
fonte
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;}
SuperJedi224
fonte
0

Perl 5, 20 bytes

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

Pega um nome de arquivo na linha de comando args e retorna a resposta no código de saída do programa

faubi
fonte
0

Python 3, 59 bytes

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

Retorna 0 para o sucesso (todos os bytes zero).

Retorna 1 para falha (pelo menos um byte diferente de zero ou arquivo de tamanho zero).

pizzapants184
fonte
Se o arquivo estiver vazio, você deverá retornar Falha.
Adám 28/08/18
0

APL (Dyalog Unicode) , 14 bytes

Programa completo. Solicita o nome do arquivo de stdin.

0=⌈/11 ¯1MAP

Experimente online!

 prompt para nome do arquivo

11 ¯1⎕MAP mapear esse arquivo para uma matriz de bits compactada

⌈/ máximo (redução); menor flutuador se vazio, caso contrário, 0 ou 1

0= é zero igual a isso?

Adão
fonte
0

Haskell, 49 bytes

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

Obviamente, se a importação não estiver incluída, serão 26 bytes.

Izaak Weiss
fonte
Eu acho que você quis dizer em readFilevez de getContets. Eu acho que você pode ler o arquivo como uma seqüência normal, comparar com =='\0'(ou melhor <'\1') e se livrar do import. Como você pode usar uma função anônima, você pode soltar o f x=e ir pointfree: (all(<'\1')<$>).readFile.
nimi
Se for um arquivo binário, você não poderá usá-lo readFile, o que gerará uma exceção ao encontrar uma sequência Unicode inválida. Bom ponto em relação ao pointfree.
Izaak Weiss
0

JavaScript (ES8), 52 bytes

Aceita um URL como argumento e retorna uma promessa que é resolvida truese o arquivo não estiver vazio e não contiver bytes nulos.

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

Zsh , 35 bytes

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

Experimente online! Saídas via código de saída.

Leia, divida em caracteres e bit a bit - ou cada ponto de código juntos.

Se o arquivo estiver vazio, o corpo do loop nunca será executado e, portanto, o loop retornará verdade. Se os valores de verdade e falsidade puderem ser trocados, o líder !poderá ser removido para um salvamento de 2 bytes.

GammaFunction
fonte