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

Как определить содержимое файла как ASCII или двоичный

Как вы определяете содержимое файла как находящееся в ASCII или двоичном формате с использованием С++?

4b9b3361

Ответ 1

Если файл содержит только десятичные байты 9, n, 13, 32 и ndash; 126, это, вероятно, чистый текстовый файл ASCII. В противном случае это не так. Тем не менее, это может быть текст в другой кодировке.

Если в добавлении к указанным выше байтам файл содержит только десятичные байты 128 – 255, это, вероятно, текстовый файл в 8-битном или переменном размере, длиной ASCII, например ISO-8859-1, UTF-8 или ASCII + Big5. Если нет, для некоторых целей вы можете остановиться здесь и считать файл двоичным. Тем не менее, это может быть текст в 16- или 32-разрядной кодировке.

Если файл не соответствует указанным выше ограничениям, просмотрите первые 2 байта файла для байтового порядка:

  • Если первые два байта hex FE FF, файл ориентировочно UTF-16 BE.
  • Если первые два байта - hex FF FE, а следующие два байта: не hex 00 00, файл ориентировочно UTF-16 LE.
  • Если первые четыре байта - hex 00 00 FE FF, файл ориентировочно UTF-32 BE.
  • Если первые четыре байта - hex FF FE 00 00, файл ориентировочно UTF-32 LE.

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

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

  • Если файл содержит только двухбайтовые слова с четырьмя байтами с десятичными значениями 9 и 13, 32, 126 и 128 или выше, файл, вероятно, UTF-16 BE.
  • Если файл содержит только малосимвольные двухбайтовые слова с десятичными значениями 9 и 13, 32, 128 и 128 или выше, файл, вероятно, UTF-16 LE.
  • Если файл содержит только четырехбайтовые слова с четырьмя байтами с десятичными значениями 9 и 13, 32 и 128 и выше, файл, вероятно, UTF-32 BE.
  • Если файл содержит только малосимвольные четырехбайтовые слова с десятичными значениями 9 и 13, 32, 126 и 128 или выше, файл, вероятно, UTF-32 LE.

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

Ответ 2

Вы повторяете его с помощью обычного цикла с stream.get() и проверяете, являются ли значения байта, которые вы читаете, <= 127. Один из способов сделать это:

int c;
std::ifstream a("file.txt");
while((c = a.get()) != EOF && c <= 127) 
    ;
if(c == EOF) {
    /* file is all ASCII */
}

Однако, как уже упоминалось, все файлы являются двоичными файлами. Кроме того, неясно, что вы подразумеваете под "ascii". Если вы имеете в виду код символа, то действительно так вы идете. Но если вы имеете в виду только буквенно-цифровые значения, вам нужно будет по-другому.

Ответ 3

Мой текстовый редактор принимает решение о наличии нулевых байтов. На практике это работает очень хорошо: двоичный файл без нулевых байтов встречается крайне редко.

Ответ 4

Посмотрите, как работает команда файла; он имеет три стратегии для определения типа файла:

В зависимости от вашей платформы и возможных файлов, которые вас интересуют, вы можете посмотреть ее реализацию или даже вызвать ее.

Ответ 5

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

ASCII - это вопрос интерпретации. Если вы откроете двоичный файл в текстовом редакторе, вы увидите, что я имею в виду.

Большинство двоичных файлов содержат фиксированный заголовок (для каждого типа), который вы можете искать, или вы можете взять расширение файла в качестве подсказки. Вы можете искать отметки порядка байтов, если вы ожидаете файлы в кодировке UTF, но они также являются необязательными.

Если вы не уточните свой вопрос более подробно, окончательный ответ не может быть.

Ответ 6

Если вопрос действительно показывает, как обнаружить только ASCII, тогда на экране будет включен лит-бит. Однако, если сан узнал, как определить, содержит ли файл текст или нет, проблема становится более сложной. ASCII - это всего лишь один - все более непопулярный - способ представления текста. Юникод-системы - UTF16, UTF32 и UTF8 стали популярными. Теоретически, их можно легко протестировать, проверив, являются ли первые два байта значком порядка байтов unicocde (BOM) 0xFEFF (или 0xFFFE, если порядок байтов отменен). Однако, поскольку эти два байта испортили много форматов файлов для Linux-систем, они не могут быть гарантированы. Кроме того, двоичный файл может начинаться с 0xFEFF.

Поиск 0x00 (или других управляющих символов) не поможет, если файл является unicode. Если файл UFT16 говорит, и файл содержит текст на английском языке, то каждый другой символ будет 0x00.

Если вы знаете язык, на котором будет записан текстовый файл, тогда можно будет проанализировать байты и статистически определить, содержит ли он текст или нет. Например, наиболее распространенным письмом на английском языке является E, за которым следует T. Так что если файл содержит много больше E и T, чем Z и X, это скорее текст. Разумеется, для этого необходимо протестировать это как ASCII и различные юникоды.

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

Ответ 7

Ну, это зависит от вашего определения ASCII. Вы можете либо проверить значения с помощью ASCII-кода < 128, либо для определенной кодировки, которую вы определяете (например, "a" - "z", "A" - "Z", "0" - "9"...) и обрабатывать файл как двоичный, если он содержит некоторые другие символы.

Вы также можете проверить регулярные разрывы строк (0x10 или 0x13,0x10) для обнаружения текстовых файлов.

Ответ 8

Чтобы проверить, вы должны открыть файл как двоичный. Вы не можете открыть файл в виде текста. ASCII фактически является подмножеством двоичного кода. После этого вы должны проверить значения байтов. ASCII имеет значения байтов 0-127, но 0-31 - контрольные символы. TAB, CR и LF являются единственными управляющими символами. Вы не можете (портативно) использовать "A" и "Z"; нет гарантии, что в ASCII (!). Если вам это нужно, вам нужно будет определить.

const unsigned char ASCII_A = 0x41; // NOT 'A'
const unsigned char ASCII_Z = ASCII_A + 25;

Ответ 9

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

Вот ссылка a The Old New Thing Article о том, как блокнот определяет тип файла ascii. Это не идеально, но интересно посмотреть, как Microsoft справится с этим.