2010-12-14 2 views
6

Tutti,java.net.URLConnection.guessContentTypeFromStream e text/plain

sto cercando di identificare i file di testo con il fine riga Mac e, all'interno di un InputStream, in silenzio convertirli in fine riga Windows o Linux (l'importante parte è il personaggio LF, davvero). In particolare, sto lavorando con diverse API che prendono InputStreams e sono bloccate a cercare \ n come newline.

A volte, ottengo file binari. Ovviamente, un file che non è simile al testo non dovrebbe avere questa sostituzione, perché il valore che corrisponde a \ r ovviamente non può essere seguito in silenzio da un \ n senza muovere male le cose.

Sto tentando di utilizzare java.net.URLConnection.guessContentTypeFromStream e di eseguire solo conversioni di fine riga se il tipo è text/plain. Sfortunatamente, "text/plain" non sembra essere nella sua gamma di valori di ritorno; tutto quello che ottengo è null per i miei file di testo flat, ed è probabilmente non sicuro assumere tutti i file non identificabili che possono essere modificati.

Quale libreria migliore (preferibilmente in un repository Maven pubblico e open-source) posso usare per fare questo? In alternativa, come posso far funzionare guessContentTypeFromStream per me? So che sto descrivendo un'applicazione intrinsecamente pericolosa e nessuna soluzione può essere perfetta, ma dovrei semplicemente considerare "null" come probabile "text/plain" e ho semplicemente bisogno di scrivere più codice per cercare prove che non sia 't?

+2

+1 per "gamma". – skaffman

risposta

2

Mi sembra che quello che stai chiedendo è determinare se un file è testuale o meno. Dato che, c'è una soluzione here che sembra giusto:

scontato, si sta parlando di Unix, bash e perl, ma il concetto è lo stesso:

A meno che non si ispezionare ogni byte del file , non hai intenzione di ottenere questo 100%. E c'è una grande prestazione colpita con l'ispezione di ogni byte. Ma dopo gli esperimenti, , ho optato per un algoritmo che funziona per me. I esamina la prima riga e dichiara che il file è binario se incontro anche un byte non di testo. Sembra un po 'rilassato , lo so, ma mi sembra di andare via con lo .

EDIT # 1:
Ampliando questo tipo di soluzione, sembra un approccio ragionevole potrebbe essere quella di verificare che il file non contiene caratteri non ASCII (a meno che non hai a che fare con i file che non sono -Inglese ... questa è un'altra soluzione). Ciò potrebbe essere fatto controllando se il contenuto del file come una stringa non corrisponde a questo:

// -- uses commons-io 
String fileAsString = FileUtils.readFileToString(new File("file-name-here")); 
boolean isTextualFile = fileAsString.matches(".*\\p{ASCII}+.*"); 

EDIT # 2
Si consiglia di provare questo come regex, o qualcosa di simile ad esso. Però, ammetto che potrebbe probabilmente usare un po 'di raffinazione.

".*(?:\\p{Print}|\\p{Space})+.*" 
+0

Stavo per usare un approccio simile a quello se tutto il resto fallisse, eccetto molto meno con garbo di una regex. (controllo byte per byte, qui arrivo!) Invece di una riga, probabilmente userò un conteggio dei caratteri fisso, principalmente per non rischiare un overrun del mio segno (...) posizione sul mio BufferedReader.Questa è una classe di caratteri che induce il mal di testa, però; qual è il modulo Java, per quelli di noi che non parlano Perl? –

+1

Mi chiedo come agisca sui file di testo con una BOM Unicode. – BalusC

+0

Le espressioni regolari specificate erano un po 'troppo tolleranti, ma tirando fuori le righe iniziali e finali * (vogliamo che i caratteri al di fuori della classe siano squalificati!) Lo ha fatto. Grazie. –