Domanda

Vale a dire, come diresti un file di archivio (jar / rar / etc.) da uno testuale (xml / txt, indipendente dalla codifica)?

È stato utile?

Soluzione

Non esiste un modo garantito, ma qui ci sono un paio di possibilità:

1) Cerca un'intestazione sul file. Sfortunatamente, le intestazioni sono specifiche del file, quindi mentre potresti essere in grado di scoprire che è un file RAR, non otterrai la risposta più generica se si tratta di testo o binario.

2) Contare il numero di caratteri rispetto ai tipi non di carattere. I file di testo saranno per lo più caratteri alfabetici mentre i file binari - specialmente quelli compressi come rar, zip e simili - tenderanno a rappresentare i byte in modo più uniforme.

3) Cerca un modello periodicamente ripetuto di newline.

Altri suggerimenti

Esegui file -bi {nomefile} . Se qualunque cosa restituisca inizia con 'text /', allora non è binario, altrimenti lo è. ; -)

L'ho fatto io. Un po 'più semplice, ma per le lingue latine, dovrebbe funzionare bene, con la regolazione del rapporto.

/**
 *  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;
}

Dai un'occhiata alla JMimeMagic .

  

jMimeMagic è una libreria Java per   determinare il tipo di file MIME o   ruscelli.

Uso della classe di file 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;
        }
    }

Ho usato questo codice e funziona abbastanza bene per il testo inglese e tedesco:

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;
}

Se il file è composto dai byte 0x09 (scheda), 0x0A (avanzamento riga), 0x0C (avanzamento modulo), 0x0D (ritorno a capo) o da 0x20 a 0x7E, è probabilmente il testo ASCII.

Se il file contiene altri caratteri di controllo ASCII, da 0x00 a 0x1F esclusi i tre precedenti, probabilmente sono dati binari.

Il testo UTF-8 segue uno schema molto specifico per tutti i byte con il bit di ordine elevato, ma non le codifiche a lunghezza fissa come ISO-8859-1. UTF-16 può spesso contenere il byte null (0x00), ma solo in ogni altra posizione.

Avresti bisogno di un'euristica più debole per qualsiasi altra cosa.

Solo per farti sapere, ho scelto un percorso piuttosto diverso. Nel mio caso, ci sono solo 2 tipi di file, le probabilità che ogni dato file sia binario sono alte. Quindi

  1. presumi che il file sia binario, prova a fare ciò che dovrebbe essere fatto (ad esempio deserializzare)
  2. cattura l'eccezione
  3. tratta il file come testuale
  4. se fallisce, c'è qualcosa che non va nel file stesso

Potresti provare lo strumento DROID .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top