Как известны типы файлов, если не из суффикса файла?


55

Я хотел бы знать, как типы файлов известны, если имена файлов не имеют суффиксов.

Например, файл с именем myfileможет быть двоичным или текстовым для начала, как система узнает, является ли файл двоичным или текстовым?


3
Просто комментарий, остальные ответы охватывают все. В настоящее время может случиться так, что из-за неправильно сконфигурированной локали или старых исполняемых файлов некоторые файлы utf-8 могут быть ошибочно обнаружены как двоичные данные из-за байтов, отличных от ascii.
Орион

19
Система не заботится. Определенные приложения могут заботиться, но у каждого из них есть свои способы справиться с этим.
jwodder

2
Обратите внимание, что даже для обычных файлов (не файлов устройств, доменных сокетов Unix, именованных каналов и т. Д.) «Тип файла» может означать две разные вещи: (1) определенный формат файла («.docx», XML, текстовый формат MS-DOS) , RTF, записи фиксированной длины, список может быть очень длинным) или (2) файл, с которым конкретное приложение знает, как обращаться (".xlsx" или ".doc" или что-то еще, есть совпадение с типом формата) , Стоит помнить об этом различии, когда речь идет о «типе файла».
Брюс Эдигер

@jwodder Система все равно. Это система, которая жалуется, что вы не можете выполнить неисполняемый файл при попытке, а не эти приложения!
Мистер Листер

1
@MrLister Правда, но исполняемый / неисполняемый не имеет ничего общего с «расширением».
user2338816

Ответы:


84

fileУтилита определяет тип файла по 3 способами:

Сначала тесты файловой системы : в рамках этих тестов к файлу вызывается один из системных вызовов семейства stat . Это возвращает различные типы файлов Unix : обычный файл, каталог, ссылка, символьное устройство, блочное устройство, именованный канал или сокет. В зависимости от этого, магические тесты сделаны.

Эти тесты магии немного сложнее. Типы файлов угадываются базой данных шаблонов, называемой волшебным файлом . Некоторые типы файлов можно определить, прочитав бит или число в определенном месте файла (например, двоичные файлы). Волшебный файл содержит « магические числа » для проверки файла, содержит ли он их или нет, и какую текстовую информацию следует печатать. Эти " магические числа " могут быть значениями 1-4Byte, строками, датами или даже регулярными выражениями. С дальнейшими тестами можно найти дополнительную информацию. В случае исполняемого файла дополнительная информация будет о том, является ли он динамически связанным или нет, удаленили нет или архитектура. Иногда несколько тестов должны пройти, прежде чем тип файла будет действительно идентифицирован. Но в любом случае, не имеет значения, сколько тестов выполнено, это всегда просто хорошее предположение .

Вот первые 8 байтов в файле некоторых общих типов файлов, которые могут помочь нам понять, как могут выглядеть эти магические числа:

             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

Если тип файла не может быть найден во время магических тестов, файл выглядит как текстовый файл и fileищет кодировку содержимого. Кодировка отличается различными диапазонами и последовательностями байтов, которые составляют печатный текст в каждом наборе.

Разрывы строк также исследуются в зависимости от их значений HEX:

  • 0A( \n) классифицирует прекращенный файл Un * x / Linux / BSD / OSX
  • 0D 0A( \r\n) являются файлами из операционных систем Microsoft
  • 0D( \r) будет Mac OS до версии 9
  • 15( \025) будет IBM AIX

Теперь языковые тесты начинаются. Если это текстовый файл, в файле ищутся определенные строки, чтобы выяснить, какой язык он содержит (C, Perl, Bash). Некоторые языки сценариев также могут быть определены через hashbang ( #!/bin/interpreter) в первой строке сценария.

Если к файлу ничего не применяется, тип файла не может быть определен и fileпросто печатает «данные».

Итак, вы видите, что суффикс не нужен. Суффикс в любом случае может сбить с толку, если задан неправильно.


4
Существует также общая база данных MIME freedesktop.org, которая используется практически всеми приложениями X11. Это похоже на концепцию того file(1), что делает, но с (очень) другой реализацией.
lcd047

4
Обратите внимание, что результат этого процесса в основном является предположением, и не следует полагаться на что-либо важное. (Удобные функции, такие как
выбор

Поэтому, если я добавлю% PNG вверху текстового файла, он будет отображаться как файл png. Правильно??
сага

@saga Если вы правильно выбрали кодировку и если вместо знака процента ставите знак промилле, то: возможно. Там могут быть дополнительные тесты.
Bananguin

19

Часто это не волнует. Вы просто передаете это программе, и она либо интерпретирует, либо нет. Может быть бесполезно открывать .jpg в текстовом редакторе, но вам не мешают это сделать. Расширение, как и остальная часть имени файла, предназначено для удобства людей.

Также возможно создать файлы, которые могут быть правильно интерпретированы несколькими способами. Поскольку формат файла ZIP начинается с заголовка в конце файла , вы можете добавить другие элементы вперед, и он все равно будет загружен в виде файла ZIP. Это обычно используется для создания самораспаковывающихся zip-файлов.


4
Последний абзац: « Фанки-форматы файлов» - интересная беседа на эту тему, представляющая, например, jpeg, которая также является программой java hello world, после того, как AES зашифровывает ее, она становится PNG, или после 3DES, расшифровывающей ее, она становится PDF и т. Д. ( все с «интересным» содержанием, т.е. не только с белым шумом или артефактами)
Хаген фон Айцен

14

Эта информация обычно находится в заголовке файла. Команда fileанализирует цель и сообщает вам информацию о файле. Большая часть информации часто получается из заголовков файлов, которые часто бывают первые несколько байтов файла (см. Ниже). Заголовки используются системой, чтобы выяснить, как обрабатывать файлы. #!/bin/bashв начале файла указывается системе использовать оболочку bash для интерпретации следующего сценария. ELFсообщает системе, что это исполняемый файл 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

Примеры заголовков файлов:

[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

3
Это довольно обманчиво. Unix-файлы сами по себе не имеют заголовка. Команда fileпытается угадать из содержимого файла, как файл, вероятно, предназначен для использования. Это не безошибочно.
Нейт Элдридж

Вы правы в том, как вы объяснили поведение file. Это на самом деле сделать анализ файла. Тем не менее, большинство типов файлов идентифицируются по заголовкам. 0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............является заголовком исполняемого файла ELF (первые несколько байтов / bin / ls). Аналогично, #!/bin/bashв верхней части ASCII-файла он будет определяться как сценарий оболочки. Другой пример: 0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR(.png изображение)
h3rrmiller

2
Но ваш ответ звучит так, будто заголовок является неотъемлемой чертой файла Unix. Текстовые файлы, например, не имеют такого заголовка; кто-то вроде OP, вероятно, посчитал бы, что исходный файл C и исходный файл Java имеют разные «типы файлов», но заголовок для их различения отсутствует. Я бы сказал, что «тип файла» даже не имеет смысла в Unix; операционная система просто предоставляет файловую систему, и каждое приложение решает, что означает содержимое любого данного файла.
Нейт Элдридж

Я согласен. Я пытался ответить как можно проще, не спускаясь слишком много кроличьих норе.
h3rrmiller

7

Первое, что нужно проверить - это жестко закодированный тип файла, который распознается ядром. Это типы файлов, такие как каталог, специальный символьный файл, специальный блочный файл, специальный канал, сокет и символическая ссылка. Эта информация поступает из inode файла. Если файл представляет собой простой файл, следующий набор информации поступает из первых 256 байтов путем поиска шаблонов. Таким образом, текстовые файлы и исходный код на C распознаются путем изучения этих байтов. Кроме того, утилиты также ищут магическое число , которое используется для проверки и проверки типа файла. Вы можете добавить свои собственные типы файлов, которые будут распознаны, добавив информацию в файл /etc/magic. Обратитесь к странице руководства, magic(5)чтобы увидеть формат магического файла.

В более старой реализации (например, Solaris) файл /etc/magicперечислял большинство распознаваемых типов файлов.


4

Команда fileприменяет некоторую эвристику из проверки (частей) файла и создания точного предположения. Помимо этого есть некоторые особые случаи, когда можно получить дополнительную информацию; как #!в начале текстового файла, BoM (метка порядка байтов) или определенные байты заголовка форматов исполняемых файлов. В #!и двоичные знаки в исполняемых файлах используются системой , чтобы сказать им друг от друга.


4

Система не знает, является ли файл двоичным или текстовым. Во всех (AFAIK) операционных системах Unix-типа fopen(path, "rb")это точно так же, как и fopen(path "r")- bничего не дает. Это принято, потому что стандарт C должен быть переносимым на некоторые другие ОС, которые делают такое различие.


0

Я бы сказал, что «тип файла» даже не имеет смысла в Unix;

В старые добрые времена пользователей мэйнфреймов их ОС поддерживали несколько типов файлов, включая последовательный и индексный. Современные операционные системы (Un * x и, возможно, Windows) сводят к минимуму набор типов файлов (включая исполняемый, общий объект).

Также возможно создание файлов, которые могут быть правильно интерпретированы несколькими способами.

Возможно, существует сложный формат файла: фрагмент кода на C, который можно интерпретировать как описание изображения. Кроме того, существуют разные форматы, все более и более конкретные: текстовый файл, файл XML, документ SOAP.


1
С форматами файлов XPM не так уж и сложен. Я считаю «хитрым» начинать с чего-то, что является одновременно действительным JPEG и действительным ZIP-файлом.
Марк
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.