Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

Вы можете использовать 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

Вы можете определить Тип MIME из файла с

file --mime FILENAME

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

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

Что ж, если вы просто просматриваете весь файл, посмотрите, доступен ли для печати каждый символ с 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 если это доступно на вашей платформе.

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

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

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

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

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

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

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

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

$ grep -rIl ''

Двоичные файлы:

$ grep -rIL ''

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

$ grep -qI '' FILE

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

$ echo $?

Одна простая проверка заключается в том, имеет ли он \0 Персонажи.В текстовых файлах их нет.

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

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

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

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

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

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

Существуют оболочки для многих языков:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top