Question

Comment identifieriez-vous un fichier archive (jar / rar / etc.) à partir d'un fichier texte (xml / txt, indépendant de l'encodage)?

Était-ce utile?

La solution

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 à un fichier. Par conséquent, même si vous pouvez savoir 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 non-caractères. Les fichiers texte sont principalement des caractères alphabétiques, tandis que les fichiers binaires, en particulier les fichiers compressés tels que rar, zip, etc., ont tendance à avoir des octets représentés plus équitablement.

3) Recherchez un motif de nouvelles lignes qui se répète régulièrement.

Autres conseils

Exécutez le fichier -bi {nom du fichier} . Si quoi qu'il retourne commence par 'text /', alors c'est non-binaire, sinon c'est le cas. ; -)

J'ai fait celui-ci. Un peu plus simple, mais pour les langues latines, 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;
}

Consultez la bibliothèque JMimeMagic .

  

jMimeMagic est une bibliothèque Java pour   déterminer le type de fichiers MIME ou   cours d'eau.

Utilisation de fichiers Java 7, classe 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;
        }
    }

J'ai utilisé ce code et il fonctionne assez bien pour les textes anglais et allemands:

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 est composé des octets 0x09 (tabulation), 0x0A (saut de ligne), 0x0C (saut de page), 0x0D (retour chariot) ou de 0x20 à 0x7E, il s'agit probablement d'un texte ASCII.

Si le fichier contient un autre caractère de contrôle ASCII, 0x00 à 0x1F, à l'exception des trois précédents, 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 les codages de longueur fixe tels que ISO-8859-1 ne le font pas. 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 toute autre chose.

Juste pour vous faire savoir, j'ai choisi un chemin tout à fait différent. Dans mon cas, il n'y a que 2 types de fichiers, les chances qu'un fichier soit binaire sont élevées. Donc

  1. présumez que le fichier est binaire, essayez de faire ce qui est supposé être fait (par exemple, désérialiser)
  2. attraper une exception
  3. traiter le fichier en tant que texte
  4. si cela échoue, quelque chose ne va pas avec le fichier lui-même

Vous pouvez essayer l'outil DROID .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top