Подтвердить что ты не робот

Как отличить файлы 'binary' и 'text'?

Неформально большинство из нас понимают, что существуют "двоичные" файлы (объектные файлы, изображения, фильмы, исполняемые файлы, собственные форматы документов и т.д.) и "текстовые" файлы (исходный код, файлы XML, файлы HTML, электронная почта и т.д.).).

В общем, вам нужно знать содержимое файла, чтобы иметь возможность делать с ним что-нибудь полезное, и формировать эту точку зрения, если кодировка "двоичная" или "текст" , это не имеет большого значения. И, конечно, файлы просто хранят байты данных, поэтому они все "двоичные" и "текстовые" ничего не значат, не зная кодировки. И все же полезно поговорить о "двоичных" и "текстовых" файлах, но чтобы не оскорблять кого-либо с этим неточным определением, я продолжу использовать кавычки "scare".

Однако существуют различные инструменты, которые работают с широким спектром файлов, и на практике вы хотите сделать что-то другое в зависимости от того, является ли файл "текстовым" или "двоичным" . Примером этого является любой инструмент, который выводит данные на консоли. Обычный "текст" будет хорошо выглядеть и полезен. "двоичные" данные испортили ваш терминал и, как правило, не подходят для просмотра. GNU grep по крайней мере использует это различие при определении того, должен ли он выводить совпадения с консолью.

Итак, вопрос в том, как вы определяете, является ли файл "текстовым" или "двоичным" ? И ограничить дальше, как вы расскажете о Linux как файловой системе? Мне неизвестны метаданные файловой системы, которые указывают на "тип" файла, поэтому вопрос становится, путем проверки содержимого файла, как я могу определить, является ли это "текстовым" или "двоичным" ? И для простоты, ограничиваем "текст" означает символы, которые можно распечатать на пользовательской консоли. И, в частности, как вы это реализуете? (Я думал, что это подразумевалось на этом сайте, но я думаю, что в целом полезно указывать на существующий код, который делает это, я должен был указать), я действительно не понимаю, какие существующие программы я могу использовать для этого это.

4b9b3361

Ответ 1

Программное обеспечение для работы с электронными таблицами, разработанное моей компанией, считывает ряд двоичных форматов, а также текстовые файлы.

Сначала мы смотрим на первые несколько байтов для магического числа, которое мы узнаем. Если мы не распознаем магическое число любого из двоичных типов, которые мы читаем, то мы просматриваем до первых 2Кбайт файла, чтобы увидеть, является ли он UTF-8, UTF-16 или текстовый файл, закодированный в текущей кодовой странице операционной системы хоста. Если он не проходит ни одного из этих тестов, мы предполагаем, что это не тот файл, с которым мы можем иметь дело, и генерируем соответствующее исключение.

Ответ 2

Вы можете использовать команду file. Он выполняет кучу тестов в файле (man file), чтобы решить, является ли он двоичным или текстовым. Вы можете посмотреть/заимствовать его исходный код, если вам нужно сделать это с 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

Ответ 3

Вы можете определить MIME-тип файла с помощью

file --mime FILENAME

Сокращение - file -i в Linux и file -I (заглавная i) в macOS (см. комментарии).

Если он начинается с text/, он текстовый, иначе двоичный. Единственным исключением являются приложения XML. Вы можете сопоставить их с поиском +xml в конце типа файла.

Ответ 4

Что ж, если вы просто просматриваете весь файл, посмотрите, можно ли печатать каждый символ с помощью isprint(c). Это немного сложнее для Unicode.

MSDN предлагает несколько отличных советов о том, что делать.

Суть в том, чтобы сначала проверить до первых четырех байтов:

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 

Это скажет вам кодировку. Затем вы хотите использовать iswprint(c) для остальных символов в текстовом файле. Для UTF-8 и UTF-16 вам необходимо проанализировать данные вручную, так как один символ может быть представлен переменным числом байтов. Кроме того, если вы действительно анальный, вы захотите использовать вариант локали iswprint, если он доступен на вашей платформе.

Ответ 5

Perl имеет приличную эвристику. Используйте оператор -B для проверки на двоичный код (и его противоположность, -T для проверки текста). Здесь оболочка однострочный для отображения текстовых файлов:

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

(Обратите внимание, что эти подчеркивания без предшествующего доллара верны (RTFM).)

Ответ 6

Его старая тема, но, возможно, кто-то найдет это полезным. Если вам нужно решить в script, если что-то есть файл, вы можете просто сделать следующее:

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

Это приведет к типу файла, и с помощью молчащего grep вы можете решить, есть ли его текст.

Ответ 7

В большинстве программ, пытающихся определить разницу, используется эвристика, например, рассмотрение первых n байтов файла и просмотр, если эти байты все квалифицируются как "текст" или нет (т.е. все они входят в диапазон печатаемых символов ASCII). Для более точного определения всегда есть команда "файл" в UNIX-подобных системах.

Ответ 8

Вы можете использовать libmagic, который является библиотечной версией командной строки Unix file.

Есть обертки для многих языков:

Ответ 9

Чтобы перечислить имена текстовых файлов в текущем каталоге /subdirs:

$ grep -rIl ''

Binaries:

$ grep -rIl ''

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

$ grep -qI '' FILE

тогда статус выхода "0" означает, что файл является текстом; '1' - двоичный. Можно проверить:

$echo $?

Ответ 10

Одна простая проверка - если у нее есть символы \0. Текстовые файлы не имеют их.

Ответ 11

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

Этот файл, называемый магией, исторически хранился в /etc, хотя это может быть в /usr/share в некоторых дистрибутивах. Магический файл определяет смещения значений, которые, как известно, существуют в файле, и затем может исследовать эти местоположения, чтобы определить тип файла.

Структура и описание магического файла можно найти, обратившись к соответствующей странице руководства (man magic)

Что касается реализации, которая может быть найдена в file.c, однако соответствующая часть команды файла определяет, это читаемый текст или нет:

/* 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 */
    }