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

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

Логика следующие: "Если первые 500 байтов файла содержат 5 или больше Управляющих символов - сообщает он как двоичный файл"

спасибо.

public boolean isAsciiText(String fileName) throws IOException {

    InputStream in = new FileInputStream(fileName);
    byte[] bytes = new byte[500];

    in.read(bytes, 0, bytes.length);
    int x = 0;
    short bin = 0;

    for (byte thisByte : bytes) {
        char it = (char) thisByte;
        if (!Character.isWhitespace(it) && Character.isISOControl(it)) {

            bin++;
        }
        if (bin >= 5) {
            return false;
        }
        x++;
    }
    in.close();
    return true;
}
6
задан James Raitsev 8 November 2011 в 16:07
поделиться

6 ответов

Поскольку вы называете этот класс «isASCIIText», вы точно знаете, что ищете. Другими словами, это не isTextInCurrentLocaleEncoding. Таким образом, вы можете быть более точными с помощью:

if (thisByte < 32 || thisByte > 127) bin++;

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

3
ответ дан 10 December 2019 в 00:32
поделиться

x , похоже, ничего не делает.

Что делать, если размер файла меньше 500 байт?

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

Должен обрабатывать исключение, если файл не может быть открыт или прочитан и т. Д.

3
ответ дан 10 December 2019 в 00:32
поделиться
  1. Сбой, если размер файла меньше 500 байт

  2. Строка char it = (char) thisByte; концептуально сомнительна, она смешивает концепции байтов и символов, т.е. неявно предполагает, что кодировка - однобайтный = один символ (они исключают кодировки Unicode). В частности, это не удается, если файл закодирован в UTF-16.

  3. Возврат внутри цикла (немного плохая практика IMO) забывает закрыть файл.

3
ответ дан 10 December 2019 в 00:32
поделиться
  1. Вы игнорируете то, что возвращает read (), что, если файлы короче 500 байт?
  2. Когда вы возвращаете false, вы не закрываете файл.
  3. При преобразовании байта в символ вы предполагаете, что ваш файл имеет 7-битный код ASCII.
0
ответ дан 10 December 2019 в 00:32
поделиться

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

Кроме того, почему сравнение с управляющими символами ISO? Это не "двоичный" файл, это "файл, содержащий 5 или более управляющих символов". На мой взгляд, лучшим подходом к ситуации было бы инвертировать проверку - написать вместо нее функцию isAsciiText, которая утверждает, что все символы в файле (или в первых 500 байтах, если хотите) находятся в наборе байт, которые известны как хорошие.

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

1
ответ дан 10 December 2019 в 00:32
поделиться

Это не будет работать с пакетами установки jdk для Linux или Solaris. у них есть запуск сценария оболочки, а затем большой двоичный объект данных.

Почему бы не проверить тип mime с помощью некоторой библиотеки, такой как jMimeMagic (http://http://sourceforge.net/projects/jmimemagic/) и десайда на основе mimetype, как обрабатывать файл.

0
ответ дан 10 December 2019 в 00:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: