2010-06-22 18 views
5

Ho scritto il seguente metodo per vedere se un determinato file contiene solo caratteri di testo ASCII o anche caratteri di controllo. Potresti dare uno sguardo a questo codice, suggerire miglioramenti e segnalare sviste?Come verificare se il file è binario?

La logica è la seguente: "Se le prime 500 byte di un file contengono 5 o più caratteri di controllo - riferire come file binario"

grazie.

public boolean isAsciiText(String fileName) throws IOException { 

    InputStream in = new FileInputStream(fileName); 
    byte[] bytes = new byte[500]; 

    in.read(bytes, 0, bytes.length); 
    int x = 0; 
    short bin = 0; 

    for (byte thisByte : bytes) { 
     char it = (char) thisByte; 
     if (!Character.isWhitespace(it) && Character.isISOControl(it)) { 

      bin++; 
     } 
     if (bin >= 5) { 
      return false; 
     } 
     x++; 
    } 
    in.close(); 
    return true; 
} 

risposta

3

Dato che chiami questa classe "isASCIIText", sai esattamente quello che stai cercando. In altre parole, non è "isTextInCurrentLocaleEncoding". Così si può essere più precisi con:

if (thisByte < 32 || thisByte > 127) bin++; 

modificare, molto tempo dopo — è sottolineato in un commento che questo semplice controllo sarebbe scattato da un file di testo che è iniziato con un sacco di nuove righe. Probabilmente sarebbe meglio usare una tabella di byte "ok" e includere caratteri stampabili (inclusi ritorno a capo, newline e tab, e possibilmente form feed anche se non credo che molti documenti moderni li usino), e quindi controllare la tavola.

+0

È una tragedia che è contrassegnata come la risposta corretta, quando questo algoritmo classificherebbe un file che contiene "questo \ r \ nis \ r \ nonly \ r \ ntext" come binario. – Ingo

+1

@Ingo true; sarebbe meglio controllare il rapporto tra i caratteri di controllo e i non controlli e anche verificare casi speciali come i caratteri di controllo comuni nel testo. Ero così giovane quando ho digitato questa risposta :) – Pointy

3

x non sembra fare nulla.

Cosa succede se il file è inferiore a 500 byte?

Alcuni file binari hanno una situazione in cui è possibile avere un'intestazione per i primi N byte del file che contiene alcuni dati utili per un'applicazione ma che la libreria a cui appartiene il binario non interessa. Si potrebbe facilmente avere 500+ byte di ASCII in un preambolo come questo seguito da dati binari nel seguente gigabyte.

dovrebbe gestire un'eccezione se il file non può essere aperto o leggere, ecc

1

La prima cosa che ho notato - non correlato alla tua domanda effettiva, ma si dovrebbe essere chiudendo il tuo flusso di input in un blocco finally per garantire è sempre fatto. Solitamente questo si limita a gestire le eccezioni, ma nel tuo caso non chiuderai nemmeno i flussi di file quando restituisci false.

A parte questo, perché il confronto con i caratteri di controllo ISO? Quello non è un file "binario", è un "file che contiene 5 o più caratteri di controllo". A mio avviso, un modo migliore per affrontare la situazione sarebbe quello di invertire il controllo - scrivere invece una funzione isAsciiText che asserisce che tutti i caratteri nel file (o nei primi 500 byte se lo si desidera) sono in un set di byte che sono noto come.

In teoria, solo il controllo delle prime centinaia di byte di un file può metterti nei guai se si tratta di un file composito di ordinamento (ad es. Testo con immagini incorporate), ma in pratica sospetto che ogni file abbia dati di intestazione binari all'inizio, quindi probabilmente stai bene.

0
  1. Si ignora cosa legge() restituisce, cosa succede se i file sono più brevi di 500 byte?
  2. Quando si restituisce false, non si chiude il file.
  3. Quando si converte il byte in char, si presuppone che il file sia ASCII a 7 bit.
0

Questo non funzionerebbe con i pacchetti di installazione jdk per linux o solaris.hanno un inizio shell-script e quindi un blob di dati bi.

perché non controllare il tipo mime utilizzando una libreria come jMimeMagic (http://http://sourceforge.net/projects/jmimemagic/) e deside in base al mimetype come gestire il file.

3
  1. FAIL male se la dimensione del file è inferiore a 500 byte

  2. La linea char it = (char) thisByte; è concettualmente dubbia, si mescola byte e chars concetti, cioè. presuppone implicitamente che la codifica sia di un byte = un carattere (esclude le codifiche Unicode). In particolare, fallisce se il file è codificato in UTF-16.

  3. Il ritorno all'interno del ciclo (pratica leggermente errata IMO) si dimentica di chiudere il file.

Problemi correlati