2010-12-14 11 views
6

Todo,java.net.URLConnection.guessContentTypeFromStream y text/plain

Estoy tratando de identificar archivos de texto plano con los finales de línea de Mac y, dentro de un InputStream, en silencio convertirlos a finales de línea de Windows o Linux (el importante parte es el personaje LF, realmente). Específicamente, estoy trabajando con varias API que toman InputStreams y están encerradas para buscar \ n como nuevas líneas.

A veces, obtengo archivos binarios. Obviamente, un archivo que no es de texto no debería tener esta sustitución hecha, porque el valor que le corresponde a \ r obviamente no puede ser seguido silenciosamente por \ n sin alterar las cosas mal.

Estoy intentando usar java.net.URLConnection.guessContentTypeFromStream y solo estoy realizando conversiones en la línea final si el tipo es texto/normal. Desafortunadamente, "text/plain" no parece estar en su gama de valores de retorno; todo lo que obtengo es null para mis archivos de texto planos, y posiblemente no sea seguro suponer que se pueden modificar todos los archivos no identificables.

¿Qué mejor biblioteca (preferiblemente en un repositorio público de Maven y código abierto) puedo usar para hacer esto? Alternativamente, ¿cómo puedo hacer que guessContentTypeFromStream me funcione? Sé que estoy describiendo una aplicación inherentemente peligrosa y ninguna solución puede ser perfecta, pero debería simplemente tratar "nulo" como probable que sea "texto/simple" y simplemente necesito escribir más código para buscar evidencia de que no es ¿t?

+2

+1 para "gama". – skaffman

Respuesta

2

Me parece que lo que está preguntando es determinar si un archivo es textual o no. Dado que, hay una solución here que parece derecho:

Por supuesto, él está hablando de Unix, bash y Perl, pero el concepto es el mismo:

A menos que inspeccionar todos los bytes del archivo , no va a obtener este 100%. Y hay un gran rendimiento golpeado con la inspección de cada byte. Pero después de algunos experimentos, me decidí por un algoritmo que funciona para mí. I examino la primera línea y declaro que el archivo es binario si encuentro incluso un byte no textual. Parece un poco flojo , lo sé, pero parece alejarse con él.

editar # 1:
Ampliando este tipo de solución, que parece un enfoque razonable sería asegurar el archivo no contiene caracteres no ASCII (a menos que usted está tratando con archivos que no son -Inglés ... esa es otra solución). Esto podría hacerse mediante la comprobación de si el contenido del archivo como una cadena no coincide con esto:

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

editar # 2
Es posible que desee probar esto como su expresión regular, o algo parecido. Sin embargo, admitiré que podría usar algo de refinación.

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

Iba a utilizar un enfoque similar al de todos los demás, excepto con mucha menos gracia que una expresión regular. (¡inspección de byte a byte, aquí vengo!) En lugar de una línea, probablemente usaré un número fijo de caracteres, principalmente para no arriesgar un exceso de mi posición de marca (...) en mi BufferedReader.Sin embargo, esa es una clase de personaje que induce al dolor de cabeza; ¿Cuál es la forma de Java, para aquellos de nosotros que no hablan Perl? –

+1

Me pregunto cómo actúa eso en los archivos de texto con una lista de materiales Unicode. – BalusC

+0

Las expresiones regulares especificadas eran un poco demasiado tolerantes, pero eliminando el principio y el final. * (Queremos que personajes fuera de la clase lo descalifiquen) lo hizo. Gracias. –