Как я могу отличить "двоичные" и "текстовые" файлы?



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



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



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



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

958   11  

11 ответов:

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

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

можно использовать

вы можете определить тип MIME файла

file --mime FILENAME

итог:file -i на Linux и file -I (capital 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-подобных системах.

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

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

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

одна простая проверка, если он имеет символы. Текстовые файлы не имеют их.

Как уже говорилось ранее * операционные системы 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] != '2' && buf[i] != '3'
            )
           )
            return 0;   /* not all ASCII */
    }

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

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

В списке имен текстовый файл в текущей директории/подкаталоги:

$ grep -rIl ''

файлы:

$ grep -rIL ''

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

$ grep -qI '' FILE

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

$ echo $?

Comments

    Ничего не найдено.