Как проверить, является ли файл простым текстом? - PullRequest
6 голосов
/ 02 июля 2011

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

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

EDIT:

Что ожидается от пользователя : текстовый файл, содержащий URL-адреса.

Чего я хочу избежать : пользователь загружает файл MP3 или документ из MS Word (примеры).

Ответы [ 6 ]

5 голосов
/ 02 июля 2011

Файл представляет собой просто серию байтов, и без дополнительной информации вы не можете сказать, должны ли эти байты быть кодовыми точками в некотором строковом кодировании (скажем, ASCII или UTF-8 или ANSI-что-то) или что-то еще. Вам придется прибегнуть к эвристике, такой как:

  • Попробуйте проанализировать файл в нескольких известных кодировках и посмотреть, удастся ли выполнить синтаксический анализ. Если это так, скорее всего, у вас есть текстовый файл.
  • Если вы ожидаете, что текстовые файлы только на западных языках, вы можете предположить, что большинство символов находится в диапазоне ASCII (0..127), а точнее (33..127) плюс пробел (табуляция, новая строка, перенос возвращение, пробел). Подсчитайте вхождения каждого отдельного байтового значения, и если подавляющая часть вашего документа находится в наборе «типичных западных символов», обычно можно предположить, что это текстовый файл.
  • Расширение предыдущего подхода; выберите достаточно большое количество текста на языках, которые вы ожидаете, и создайте профиль частоты символов. Чтобы проверить ваш файл, сравните профиль частоты символов в файле с данными теста и посмотрите, достаточно ли он близок.

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

2 голосов
/ 02 июля 2011

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

Полагаю, вы хотите проверить, есть ли в вашем вводе символы <32. Если вы можете с уверенностью предположить, что ваш текст имеет многобайтовую кодировку, вы можете просто просмотреть весь файл и прервать его, если вы попали в байт в диапазоне [0, 32) (исключая 9, 10, 13 и все, что угодно, кроме как в «текст» - или в худшем случае <em>только проверка на нулевые байты [спасибо, tdammers!]). Если вы можете ожидать получения текста в кодировке UTF-16 или UTF-32, вам придется работать усерднее.

1 голос
/ 03 июля 2011

Вы также можете проверить, являются ли начальные байты BoM, что должно указывать файл в UTF:

- UTF-8     => 0xEF, 0xBB, 0xBF
- UTF-16 BE => 0xFE, 0xFF
- UTF-16 LE => 0xFF, 0xFE

rossum

1 голос
/ 02 июля 2011

Если вы не хотите угадывать по расширению файла , вы можете прочитать первую часть файла.Но следующей проблемой будет кодировка символов.Используя BufferedInputStream (mark() до и reset() после), оберните с InputStreamReader с кодировкой "ISO-8859-1" и посчитайте прочитанный символ с Character.isLetterOrDigit() или Character.isWhitespace(), чтобы получить соотношение типичного текстового содержимого.Я думаю, что для текстового файла это соотношение должно быть более 80%.

Вы также можете попробовать другую кодировку, например UTF-8, но у вас могут возникнуть проблемы с недопустимыми символами, если это не UTF-8.

0 голосов
/ 30 мая 2014

Вы можете вызвать команду оболочки file -i ${filename} из Java и проверить вывод, чтобы увидеть, содержит ли он что-то вроде charset=binary.Если это так, то это двоичный файл.В противном случае это текстовый файл.

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

'file -i ${path/to/myfile}'.execute().getText().contains('charset=binary')

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

0 голосов
/ 02 июля 2011

Вы должны создать фильтр, который просматривает описание файла и проверяет текст.

...