Определение двоичного / текстового типа файла в Java? - PullRequest
38 голосов
/ 07 марта 2009

А именно, как бы вы отличили архивный файл (jar / rar / и т.

Ответы [ 10 ]

17 голосов
/ 07 марта 2009

Там нет гарантированного пути, но вот несколько возможностей:

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

2) Подсчитайте количество символов против не-символьных типов. Текстовые файлы будут в основном алфавитными символами, в то время как двоичные файлы, особенно сжатые, такие как rar, zip и т. Д., Будут иметь более равномерное представление байтов.

3) Ищите регулярно повторяющуюся последовательность новых строк.

10 голосов
/ 21 октября 2009

Пробег file -bi {filename}. Если все, что он возвращает, начинается с 'text /', то оно не является двоичным, в противном случае это так. ; -)

9 голосов
/ 23 ноября 2012

Я сделал это. Немного проще, но для латинских языков все должно работать нормально с настройкой соотношения.

/**
 *  Guess whether given file is binary. Just checks for anything under 0x09.
 */
public static boolean isBinaryFile(File f) throws FileNotFoundException, IOException {
    FileInputStream in = new FileInputStream(f);
    int size = in.available();
    if(size > 1024) size = 1024;
    byte[] data = new byte[size];
    in.read(data);
    in.close();

    int ascii = 0;
    int other = 0;

    for(int i = 0; i < data.length; i++) {
        byte b = data[i];
        if( b < 0x09 ) return true;

        if( b == 0x09 || b == 0x0A || b == 0x0C || b == 0x0D ) ascii++;
        else if( b >= 0x20  &&  b <= 0x7E ) ascii++;
        else other++;
    }

    if( other == 0 ) return false;

    return 100 * other / (ascii + other) > 95;
}
9 голосов
/ 07 марта 2009

Посмотрите библиотеку JMimeMagic .

jMimeMagic - это библиотека Java для определение типа файлов MIME или потоков.

7 голосов
/ 06 октября 2016

Использование Java 7 Files class http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType(java.nio.file.Path)

boolean isBinaryFile(File f) throws IOException {
        String type = Files.probeContentType(f.toPath());
        if (type == null) {
            //type couldn't be determined, assume binary
            return true;
        } else if (type.startsWith("text")) {
            return false;
        } else {
            //type isn't text
            return true;
        }
    }
5 голосов
/ 14 июля 2012

Я использовал этот код, и он хорошо работает для английского и немецкого текста:

private boolean isTextFile(String filePath) throws Exception {
    File f = new File(filePath);
    if(!f.exists())
        return false;
    FileInputStream in = new FileInputStream(f);
    int size = in.available();
    if(size > 1000)
        size = 1000;
    byte[] data = new byte[size];
    in.read(data);
    in.close();
    String s = new String(data, "ISO-8859-1");
    String s2 = s.replaceAll(
            "[a-zA-Z0-9ßöäü\\.\\*!\"§\\$\\%&/()=\\?@~'#:,;\\"+
            "+><\\|\\[\\]\\{\\}\\^°²³\\\\ \\n\\r\\t_\\-`´âêîô"+
            "ÂÊÔÎáéíóàèìòÁÉÍÓÀÈÌÒ©‰¢£¥€±¿»«¼½¾™ª]", "");
    // will delete all text signs

    double d = (double)(s.length() - s2.length()) / (double)(s.length());
    // percentage of text signs in the text
    return d > 0.95;
}
3 голосов
/ 15 марта 2009

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

  1. предположить, что файл является двоичным, попробуйте сделать то, что должно быть сделано (например, десериализовать)
  2. поймать исключение
  3. рассматривать файл как текстовый
  4. если это не помогло, что-то не так с самим файлом
3 голосов
/ 07 марта 2009

Если файл состоит из байтов 0x09 (вкладка), 0x0A (перевод строки), 0x0C (перевод формы), 0x0D (возврат каретки) или от 0x20 до 0x7E, то это, вероятно, текст ASCII.

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

Текст UTF-8 следует очень специфическому шаблону для любых байтов с битами старшего разряда, но кодировки фиксированной длины, такие как ISO-8859-1, не делают. UTF-16 часто может содержать нулевой байт (0x00), но только в любой другой позиции.

Вам понадобится более слабая эвристика для всего остального.

2 голосов
/ 07 марта 2009
1 голос
/ 07 марта 2009

Вы можете попробовать инструмент DROID .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...