Gostaria de saber como os tipos de arquivo são conhecidos se os nomes de arquivos não tiverem sufixos.
Por exemplo, um arquivo nomeado myfile
pode ser binário ou texto, como o sistema sabe se o arquivo é binário ou texto?
Gostaria de saber como os tipos de arquivo são conhecidos se os nomes de arquivos não tiverem sufixos.
Por exemplo, um arquivo nomeado myfile
pode ser binário ou texto, como o sistema sabe se o arquivo é binário ou texto?
Respostas:
O file
utilitário determina o tipo de arquivo de três maneiras:
Primeiro, o sistema de arquivos testa : Nesses testes, uma das chamadas do sistema da família stat é chamada no arquivo. Isso retorna os diferentes tipos de arquivo unix : arquivo regular, diretório, link, dispositivo de caractere, dispositivo de bloco, pipe nomeado ou um soquete. Dependendo disso, os testes de mágica são feitos.
Os testes de mágica são um pouco mais complexos. Os tipos de arquivo são adivinhados por um banco de dados de padrões chamado arquivo mágico . Alguns tipos de arquivos podem ser determinados lendo um bit ou número em um local específico dentro do arquivo (binários, por exemplo). O arquivo mágico contém " números mágicos " para testar se ele os contém ou não e quais informações de texto devem ser impressas. Esses " números mágicos " podem ter valores de 1 a 4Byte, seqüências de caracteres, datas ou mesmo expressões regulares. Com outros testes, informações adicionais podem ser encontradas. No caso de um executável, informações adicionais seriam vinculadas ou não dinamicamente , removidasou não ou a arquitetura. Às vezes, vários testes devem passar antes que o tipo de arquivo possa ser realmente identificado. De qualquer forma, não importa quantos testes são executados, é sempre apenas um bom palpite .
Aqui estão os primeiros 8 bytes em um arquivo de alguns tipos de arquivos comuns que podem nos ajudar a ter uma ideia de como esses números mágicos podem se parecer:
Hexadecimal ASCII
PNG 89 50 4E 47|0D 0A 1A 0A ‰PNG|....
JPG FF D8 FF E1|1D 16 45 78 ÿØÿá|..Ex
JPG FF D8 FF E0|00 10 4A 46 ÿØÿà|..JF
ZIP 50 4B 03 04|0A 00 00 00 PK..|....
PDF 25 50 44 46|2D 31 2E 35 %PDF|-1.5
Se o tipo de arquivo não puder ser encontrado nos testes mágicos, o arquivo parecerá um arquivo de texto e file
procurará a codificação do conteúdo. A codificação é diferenciada pelos diferentes intervalos e sequências de bytes que constituem texto imprimível em cada conjunto.
As quebras de linha também são investigadas, dependendo de seus valores HEX:
0A
( \n
) classifica um arquivo finalizado Un * x / Linux / BSD / OSX0D 0A
( \r\n
) são arquivos de sistemas operacionais Microsoft0D
( \r
) seria o Mac OS até a versão 915
( \025
) seria IBMs AIXAgora os testes de idioma começam. Se parece ser um arquivo de texto, o arquivo é pesquisado por sequências específicas para descobrir qual idioma ele contém (C, Perl, Bash). Algumas linguagens de script também podem ser identificadas sobre o hashbang ( #!/bin/interpreter
) na primeira linha do script.
Se nada se aplica ao arquivo, o tipo de arquivo não pode ser determinado e file
apenas imprime "dados".
Então, você vê que não há necessidade de um sufixo. Um sufixo de qualquer maneira pode confundir, se definido incorretamente.
file(1)
faz, mas com uma implementação (muito) diferente.
Muitas vezes, isso não se importa. Você apenas o passa para um programa e ele o interpreta ou não. Pode não ser útil abrir um .jpg em um editor de texto, mas você não é impedido de fazer isso. A extensão, como o restante do nome do arquivo, é para a conveniência organizacional dos seres humanos.
Também pode ser possível construir arquivos que possam ser validamente interpretados de várias maneiras. Como o formato do arquivo ZIP inicia, possui um cabeçalho no final do arquivo , você pode acrescentar outras coisas à frente e ele ainda será carregado como um arquivo ZIP. Isso é comumente usado para criar arquivos zip com extração automática.
Essa informação é comumente encontrada no cabeçalho do arquivo. O file
comando analisa o destino e informa informações sobre o arquivo. Muitas informações são derivadas de cabeçalhos de arquivo, muitas vezes os primeiros bytes de um arquivo (veja abaixo). Os cabeçalhos são usados pelo sistema para descobrir como lidar com arquivos. #!/bin/bash
no início de um arquivo diz ao sistema para usar o shell bash para interpretar o seguinte script. ELF
informa ao sistema que este é um executável ELF.
[~] root@www # file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[~] root@www # file /etc/passwd
/etc/passwd: ASCII text
Exemplos de cabeçalho de arquivo:
[root@server4 ~]# xxd old_sm_logo.png | head -5
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
0000010: 0000 0134 0000 006f 0806 0000 0062 bf3c ...4...o.....b.<
[root@server4 ~]# xxd /bin/ls | head -5
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 a024 4000 0000 0000 ..>......$@.....
[root@server4 proj]# xxd resizer.sh | head -5
0000000: 2321 2f62 696e 2f62 6173 680a 5b20 2d7a #!/bin/bash.[ -z
0000010: 2022 2431 2220 5d20 2626 2065 6368 6f20 "$1" ] && echo
file
comando tenta adivinhar, a partir do conteúdo do arquivo, como o arquivo provavelmente deve ser usado. Não é infalível.
file
. De fato, faz uma análise do arquivo. No entanto, a maioria dos tipos de arquivos é identificada por um tipo de cabeçalho. 0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
é um cabeçalho de um executável ELF (primeiros bytes de / bin / ls). Da mesma forma, #!/bin/bash
na parte superior de um arquivo ASCII, ele seria identificado como um script de shell. Outro exemplo: 0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
(a .png image)
A primeira coisa a verificar é o tipo de arquivo codificado que é reconhecido pelo kernel. Esses são os tipos de arquivo, como diretório, arquivo especial de caractere, arquivo especial de bloco, arquivo especial de tubo, soquete e link simbólico. Esta informação vem do inode do arquivo. Se o arquivo for um arquivo simples, o próximo conjunto de informações virá dos primeiros 256 bytes, procurando por padrões. Assim, os arquivos de texto e o código fonte C são reconhecidos examinando esses bytes. Além disso, os utilitários também procuram um número mágico usado para testar e validar o tipo de arquivo. Você pode adicionar seus próprios tipos de arquivos a serem reconhecidos adicionando as informações ao arquivo /etc/magic
. Consulte a página do manual para magic(5)
ver o formato do arquivo mágico.
Na implementação mais antiga (Solaris, por exemplo), o arquivo /etc/magic
enumerava a maioria dos tipos de arquivos reconhecidos.
O file
comando aplica algumas heurísticas ao inspecionar (partes do) arquivo e fazer uma estimativa qualificada. Além disso, existem alguns casos especiais em que informações adicionais podem ser obtidas; como #!
no início de um arquivo de texto, um BoM (byte order mark) ou bytes de cabeçalho específicos de formatos de arquivo executáveis. As #!
marcas e binárias nos executáveis são usadas pelo sistema para diferenciá-las.
O sistema não sabe se um arquivo é binário ou texto. Em todos os sistemas operacionais do tipo Unix (AFAIK), fopen(path, "rb")
é exatamente o mesmo que fopen(path "r")
- b
não tem efeito. É aceito porque o padrão C precisa ser portátil para outros sistemas operacionais que fazem essa distinção.
Eu argumentaria que "tipo de arquivo" nem sequer é um conceito significativo no Unix;
Nos velhos tempos dos computadores mainframe, os SOs suportavam vários tipos de arquivos, incluindo seqüencial e sequencial de índice. Os sistemas operacionais modernos (Un * xe possivelmente o Windows) reduzem o conjunto de tipos de arquivo ao mínimo (incluindo objeto compartilhado e executável).
Também pode ser possível construir arquivos que possam ser validamente interpretados de várias maneiras
É possível, existe um formato de arquivo complicado: um pedaço de código C que pode ser interpretado como uma descrição da imagem. Além disso, existem diferentes formatos cada vez menos específicos: arquivo de texto, arquivo XML, um documento SOAP.