А именно, как вы скажете архив (jar/rar/etc.) из текстового (xml/txt, независимого от кодирования) одного?
Определение типа двоичного/текстового файла в Java?
Ответ 1
Там нет гарантированного способа, но вот несколько возможностей:
1) Найдите заголовок в файле. К сожалению, заголовки зависят от файлов, поэтому, хотя вы можете узнать, что это RAR файл, вы не получите более общий ответ: текстовый или двоичный.
2) Подсчитайте количество символов и несимвольных типов. Текстовые файлы будут в основном алфавитными символами, в то время как двоичные файлы - особенно сжатые, такие как rar, zip и т.д. - будут иметь тенденцию иметь более равномерно представленные байты.
3) Найдите регулярный повторяющийся узор новых строк.
Ответ 2
Запустите file -bi {filename}
. Если все, что возвращается, начинается с "text/", то оно не является двоичным, иначе оно есть.; -)
Ответ 3
Посмотрите на библиотеку JMimeMagic.
jMimeMagic - это библиотека Java для определение типа файлов MIME или потоков.
Ответ 4
Я сделал это. Немного проще, но для латинских языков он должен работать нормально, с регулировкой отношения.
/**
* 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;
}
Ответ 5
Я использовал этот код, и он хорошо работает для английского и немецкого текста:
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ßöäü\\.\\*!\"§\\$\\%&/()=\\[email protected]~'#:,;\\"+
"+><\\|\\[\\]\\{\\}\\^°²³\\\\ \\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;
}
Ответ 6
Если файл состоит из байтов 0x09 (вкладка), 0x0A (строка), 0x0C (фид формы), 0x0D (возврат каретки) или 0x20 - 0x7E, то это, вероятно, текст ASCII.
Если файл содержит любой другой управляющий символ ASCII, от 0x00 до 0x1F, исключая три выше, то это, вероятно, двоичные данные.
Текст UTF-8 следует очень конкретному шаблону для любых байтов с битом высокого порядка, но кодировки с фиксированной длиной, такие как ISO-8859-1, не используются. UTF-16 часто может содержать нулевой байт (0x00), но только в любой другой позиции.
Вам понадобится более слабая эвристика для чего-нибудь еще.
Ответ 7
Просто чтобы вы знали, я выбрал совершенно другой путь. В моем случае есть только 2 типа файлов, вероятность того, что любой файл будет бинарным, высока. Так
- предположим, что файл двоичный, попробуйте сделать то, что должно быть сделано (например, deserialize)
- исключение catch
- обрабатывать файл как текстовый
- Если это не удается, что-то не так с самим файлом
Ответ 8
Использование класса файлов Java 7 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;
}
}
Ответ 9
Ответ 10
Вы можете попробовать инструмент DROID.