À savoir, comment diriez-vous un fichier d'archive (jar/rar/etc.) À partir d'un fichier textuel (xml/txt, indépendant de l'encodage)?
Il n'y a pas de moyen garanti, mais voici quelques possibilités:
1) Recherchez un en-tête dans le fichier. Malheureusement, les en-têtes sont spécifiques au fichier, donc bien que vous puissiez découvrir qu'il s'agit d'un fichier RAR, vous n'obtiendrez pas la réponse plus générique qu'il s'agisse de texte ou de binaire.
2) Comptez le nombre de types de caractères par rapport aux types sans caractère. Les fichiers texte seront principalement des caractères alphabétiques tandis que les fichiers binaires - en particulier ceux compressés comme rar, Zip, etc. - auront tendance à être représentés de manière plus uniforme.
3) Recherchez une répétition régulière de nouvelles lignes.
Utilisation de Java 7 classe Files 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;
}
}
Courir file -bi {filename}
. Si tout ce qu'il retourne commence par 'text /', alors ce n'est pas binaire, sinon c'est le cas. ;-)
J'ai fait celui-ci. Un peu plus simple, mais pour les langues à base latine, cela devrait fonctionner correctement, avec l'ajustement du rapport.
/**
* 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;
}
Jetez un œil à la bibliothèque JMimeMagic .
jMimeMagic est une bibliothèque Java pour déterminer le type MIME de fichiers ou de flux.
J'ai utilisé ce code et cela fonctionne plutôt bien pour le texte anglais et allemand:
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;
}
Si le fichier se compose des octets 0x09 (tabulation), 0x0A (saut de ligne), 0x0C (saut de page), 0x0D (retour chariot) ou 0x20 à 0x7E, il s'agit probablement du texte ASCII.
Si le fichier contient tout autre caractère de contrôle ASCII, 0x00 à 0x1F à l'exclusion des trois ci-dessus, il s'agit probablement de données binaires.
Le texte UTF-8 suit un modèle très spécifique pour tous les octets avec le bit de poids fort, mais pas les codages de longueur fixe comme ISO-8859-1. UTF-16 peut fréquemment contenir l'octet nul (0x00), mais uniquement dans toutes les autres positions.
Vous auriez besoin d'une heuristique plus faible pour autre chose.
Juste pour vous faire savoir, j'ai choisi une voie assez différente. Dans mon cas, il n'y a que 2 types de fichiers, les chances qu'un fichier donné soit binaire sont élevées. Alors
Vous pouvez essayer l'outil DROÏDE .