Pergunta

Informalmente, a maioria de nós compreender que existem arquivos 'binário' (arquivos de objetos, imagens, filmes, arquivos executáveis, formatos de documentos proprietários, etc) e arquivos 'texto' (código-fonte, arquivos XML, arquivos HTML, e-mail, etc. ).

Em geral, você precisa saber o conteúdo de um arquivo para ser capaz de fazer algo de útil com ele, e formar esse ponto de vista, se a codificação é 'binário' ou 'texto', ele realmente não importa. E de arquivos do curso apenas armazenar bytes de dados para que eles sejam todos e 'texto' 'binário' faz nada não dizer, sem saber a codificação. E, no entanto, ainda é útil para falar sobre arquivos 'binários' e 'texto', mas para evitar ofender alguém com esta definição imprecisa, vou continuar a usar aspas 'assustas'.

No entanto, existem várias ferramentas que o trabalho em uma grande variedade de arquivos e, em termos práticos, você quer fazer algo diferente com base em se o arquivo é 'text' ou 'binário'. Um exemplo disso é qualquer ferramenta que os dados saídas no console. Plain 'texto' vai olhar bem, e é útil. Dados 'binários' mexe-se o seu terminal, e geralmente não é útil olhar. GNU grep, pelo menos, os usos desta distinção ao determinar se ele deve partidas saída para o console.

Assim, a pergunta é, como você dizer se um arquivo é 'text' ou 'binário'? E para restringir é ainda, como você diz em um Linux como sistema de arquivos? Não tenho conhecimento de qualquer sistema de arquivos meta-dados que indica o 'tipo' de um arquivo, então a questão torna-se ainda mais, inspecionando o conteúdo de um arquivo, como posso dizer se é 'text' ou 'binário'? E por simplicidade, permite restringir o 'texto' para personagens médios que são imprimíveis no console do usuário. E, em particular, como é que você implementar isso? (Eu pensei que isso estava implícito neste site, mas eu acho que é útil, em geral, a ser apontada para o código que faz isso, eu deveria ter especificado existente), eu não estou realmente depois do que os programas existentes que posso usar para fazer isso.

Foi útil?

Solução

O software de planilha minha empresa faz lê um número de formatos de arquivos binários, bem como arquivos de texto.

Nós primeiro olhar para os primeiros bytes para um mágica número que reconhecer. Se não reconhecer o número mágico de qualquer um dos tipos binários que lemos, então nós olhamos até os primeiros 2K bytes do arquivo para ver se ele parece ser um UTF-8 , UTF-16 ou um arquivo de texto codificado na corrente página de código de o sistema operacional hospedeiro. Se passar nenhum destes testes, assumimos que não é um arquivo que pode lidar com e lançar uma exceção apropriada.

Outras dicas

Você pode usar o comando file. Ele faz um monte de testes sobre o arquivo (man file) para decidir se é binário ou texto. Você pode olhar para / emprestar seu código fonte se você precisa fazer isso a partir C.

file README
README: ASCII English text, with very long lines

file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

Você pode determinar o MIME tipo do arquivo com

file --mime FILENAME

A taquigrafia é file -i em Linux e file -I (capital i) no MacOS (ver comentários).

Se ele começa com text/, é texto, caso contrário binário. A única exceção são aplicações XML. Você pode combinar aqueles procurando por +xml no final do tipo de arquivo.

Bem, se você está apenas inspecionar o arquivo inteiro, ver se cada personagem é impressa com isprint(c). Ele fica um pouco mais complicado para Unicode.

Para distinguir um arquivo de texto unicode, ofertas MSDN alguns grande conselhos sobre o que fazer .

A essência do que é a primeira a inspeccionar-se aos quatro primeiros bytes:

EF BB BF     UTF-8 
FF FE        UTF-16, little endian 
FE FF        UTF-16, big endian 
FF FE 00 00  UTF-32, little endian 
00 00 FE FF  UTF-32, big-endian 

Isso irá dizer-lhe a codificação. Então, você gostaria de usar iswprint(c) para o resto dos personagens no arquivo de texto. Para UTF-8 e UTF-16, você precisa analisar os dados manualmente, pois um único caractere pode ser representado por um número variável de bytes. Além disso, se você estiver realmente anal, você vai querer usar a variante local de iswprint se que está disponível na sua plataforma.

Perl tem uma heurística decente. Use o operador -B de teste para binário (e seu oposto, -T de teste para o texto). Aqui está shell um one-liner para arquivos de texto da lista:

$ find . -type f -print0 | perl -0nE 'say if -f and -s _ and -T _'

(Note que esses sublinhados sem um dólar anterior estão corretas (RTFM).)

A maioria dos programas que tentam dizer o uso diferença uma heurística, como a análise do primeiro n bytes do arquivo e ver se esses bytes todas qualificar como 'texto' ou não (ou seja, fazer todos eles caem dentro da faixa de charcters ASCII imprimíveis). Para distiction mais fina há sempre o comando 'file' em sistemas UNIX-like.

Seu um velho tema, mas talvez alguém vai encontrar este útil. Se você tem que decidir em um script, se algo é um arquivo, em seguida, você pode simplesmente fazer assim:

if file -i $1 | grep -q text;
then 
.
.
fi

Isto irá obter o tipo de arquivo, e com um grep silenciosa você pode decidir se o seu texto.

Para listar os nomes de arquivo de texto no atual dir / subdirs:

$ grep -rIl ''

Os binários:

$ grep -rIL ''

Para verificar arquivo particular, ligeiramente modificar comando:

$ grep -qI '' FILE

então, status de saída '0' significaria o arquivo é um texto; '1' - binário. Poderia verificar:

$ echo $?

Uma verificação simples é se ele tem personagens \0. arquivos de texto não tê-los.

sistemas operacionais * nix

Como foi referido anteriormente têm essa capacidade dentro do comando file. Este comando utiliza um arquivo de configuração que define números de magia contida dentro de muitas estruturas de arquivos popular.

Este arquivo, chamado de magia foi historicamente armazenados em / etc, embora isso possa estar em / usr / share em algumas distribuições. Os define magia arquivo deslocamentos de valores conhecidos de existir dentro do arquivo e pode então examinar esses locais para determinar o tipo do arquivo.

A estrutura ea descrição do arquivo de magia pode ser encontrada consultando a página do manual relevante (homem mágico)

Como para uma implementação, bem que pode ser encontrada dentro file.c em si, porém a parte relevante do comando arquivo que determina se é texto legível ou não é o seguinte

/* Make sure we are dealing with ascii text before looking for tokens */
    for (i = 0; i < nbytes - 1; i++) {
        if (!isascii(buf[i]) ||
            (iscntrl(buf[i]) && !isspace(buf[i]) &&
             buf[i] != '\b' && buf[i] != '\032' && buf[i] != '\033'
            )
           )
            return 0;   /* not all ASCII */
    }

Você pode usar libmagic que é uma versão da biblioteca da linha de comando file Unix.

Existem wrapper para muitas línguas:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top