Me preguntaba cómo la mayoría de las personas obtienen un tipo MIME de un archivo en Java. Hasta ahora he probado dos utilidades: JMimeMagic
& Mime-Util
.
El primero me dio excepciones de memoria, el segundo no cierra sus secuencias correctamente. Me preguntaba si alguien más tenía un método / biblioteca que usaban y funcionaban correctamente.
Respuestas:
En Java 7 ahora solo puede usar
Files.probeContentType(path)
.fuente
null
hacia fuera para.xml
,.png
y.xhtml
archivos. No sé si solo estoy haciendo algo terriblemente mal, pero eso parece bastante terrible.Desafortunadamente,
no funciona, ya que este uso de URL deja un archivo bloqueado, por lo que, por ejemplo, no se puede borrar.
Sin embargo, tienes esto:
y también lo siguiente, que tiene la ventaja de ir más allá del mero uso de la extensión de archivo, y echa un vistazo al contenido
Sin embargo, como lo sugiere el comentario anterior, la tabla integrada de tipos MIME es bastante limitada, sin incluir, por ejemplo, MSWord y PDF. Por lo tanto, si desea generalizar, deberá ir más allá de las bibliotecas integradas, utilizando, por ejemplo, Mime-Util (que es una gran biblioteca, que utiliza tanto la extensión de archivo como el contenido).
fuente
FileInputStream
enBufferedInputStream
es parte crucial - de lo contrarioguessContentTypeFromStream
retornanull
(pasadoInputStream
instancia debe apoyar marcas)URLConnection
tiene un conjunto muy limitado de tipos de contenido que reconoce. Por ejemplo, no puede detectarapplication/pdf
.guessContentTypeFromName()
utiliza el$JAVA_HOME/lib/content-types.properties
archivo predeterminado puede agregar su propio archivo extendido cambiando la propiedad del sistemaSystem.setProperty("content.types.user.table","/lib/path/to/your/property/file");
La API JAF es parte de JDK 6. Mira el
javax.activation
paquete.Las clases más interesantes son
javax.activation.MimeType
- un titular de tipo MIME real - yjavax.activation.MimetypesFileTypeMap
- clase cuya instancia puede resolver el tipo MIME como Cadena para un archivo:fuente
getContentType(File)
indica javadoc for : Devuelve el tipo MIME del objeto de archivo. La implementación en esta clase llamagetContentType(f.getName())
.MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file)
Con Apache Tika solo necesita tres líneas de código :
Si tiene una consola maravillosa, simplemente pegue y ejecute este código para jugar con él:
Tenga en cuenta que sus API son ricas, puede analizar "cualquier cosa". A partir de tika-core 1.14, tiene:
Vea las apidocs para más información.
fuente
new Tika().detect(file.toPath())
para la detección basada en la extensión del archivo en lugar de la detección basada en el contenido del archivonew Tika().detect(file.getPath())
, que solo usa la extensión de archivoApache Tika ofrece en tika-core una detección de tipo mime basada en marcadores mágicos en el prefijo de transmisión.
tika-core
no busca otras dependencias, lo que lo hace tan liviano como la utilidad de detección de tipo Mime actualmente no mantenida .Ejemplo de código simple (Java 7), usando las variables
theInputStream
ytheFileName
Tenga en cuenta que MediaType.detect (...) no se puede usar directamente ( TIKA-1120 ). Se proporcionan más sugerencias en https://tika.apache.org/0.10/detection.html .
fuente
Metadata.RESOURCE_NAME_KEY
se puede omitir +1 (si no tiene ninguno o no puede confiar en el nombre original), pero en ese caso obtendrá resultados incorrectos en algunos casos (documentos de oficina, por ejemplo).Si es un desarrollador de Android, puede usar una clase de utilidad
android.webkit.MimeTypeMap
que asigna tipos MIME a extensiones de archivo y viceversa.El siguiente fragmento de código puede ayudarlo.
fuente
De roseindia :
fuente
Si está atascado con Java 5-6, entonces esta clase de utilidad del producto de código abierto servo .
Solo necesitas esta función
Sondea los primeros bytes del contenido y devuelve los tipos de contenido en función de ese contenido y no por extensión de archivo.
fuente
He publicado mi paquete Java SimpleMagic que permite la determinación del tipo de contenido (tipo mime) a partir de archivos y conjuntos de bytes. Está diseñado para leer y ejecutar los archivos mágicos de comando del archivo Unix (1) que forman parte de la mayoría de las configuraciones de ~ Unix OS.
Intenté Apache Tika pero es enorme con toneladas de dependencias,
URLConnection
no usa los bytes de los archivos yMimetypesFileTypeMap
también solo mira los nombres de los archivos.Con SimpleMagic puedes hacer algo como:
fuente
Para contribuir con mis 5 centavos:
TL, DR
Uso MimetypesFileTypeMap y agrego cualquier mime que no está allí y lo necesito específicamente, en el archivo mime.types.
Y ahora, la lectura larga:
En primer lugar, la lista de tipos MIME es enorme , consulte aquí: https://www.iana.org/assignments/media-types/media-types.xhtml
Me gusta usar las instalaciones estándar proporcionadas por JDK primero, y si eso no funciona, iré a buscar otra cosa.
Determinar el tipo de archivo desde la extensión del archivo
Desde 1.6, Java tiene MimetypesFileTypeMap, como se señala en una de las respuestas anteriores, y es la forma más sencilla de determinar el tipo mime:
En su implementación de vainilla esto no hace mucho (es decir, funciona para .html pero no para .png). Sin embargo, es muy simple agregar cualquier tipo de contenido que pueda necesitar:
Las entradas de ejemplo para archivos png y js serían:
Para el formato de archivo mime.types, vea más detalles aquí: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html
Determinar el tipo de archivo a partir del contenido del archivo
Desde 1.7, Java tiene java.nio.file.spi.FileTypeDetector , que define una API estándar para determinar un tipo de archivo en forma específica de implementación .
Para buscar el tipo mime para un archivo, simplemente use Archivos y haga esto en su código:
La definición de API proporciona recursos que admiten la determinación del tipo de archivo MIME a partir del nombre del archivo o del contenido del archivo (bytes mágicos). Es por eso que el método probeContentType () arroja IOException, en caso de que una implementación de esta API utilice la ruta que se le proporciona para intentar abrir el archivo asociado.
Nuevamente, la implementación vainilla de esto (la que viene con JDK) deja mucho que desear.
En un mundo ideal en una galaxia muy, muy lejana, todas estas bibliotecas que intentan resolver este problema de tipo de archivo a mimo simplemente implementarían java.nio.file.spi.FileTypeDetector , colocarías el jar de la biblioteca de implementación preferida archivo en su classpath y eso sería todo.
En el mundo real, en el que necesita la sección TL, DR, debe encontrar la biblioteca con la mayoría de las estrellas al lado de su nombre y usarla. Para este caso en particular, no necesito uno (todavía;)).
fuente
Intenté varias formas de hacerlo, incluidas las primeras que dijo @Joshua Fox. Pero algunos no reconocen los tipos MIME frecuentes, como los archivos PDF, y otros no pueden ser confiables con archivos falsos (intenté con un archivo RAR con la extensión cambiada a TIF). La solución que encontré, como también lo dijo @Joshua Fox de manera superficial, es usar MimeUtil2 , así:
fuente
Es mejor utilizar la validación de dos capas para cargar archivos.
Primero puede verificar el mimeType y validarlo.
En segundo lugar, debe buscar convertir los primeros 4 bytes de su archivo a hexadecimal y luego compararlo con los números mágicos. Entonces será una forma realmente segura de verificar las validaciones de archivos.
fuente
Esta es la forma más simple que encontré para hacer esto:
fuente
Si está trabajando con un Servlet y el contexto del servlet está disponible para usted, puede usar:
fuente
getServletContext
?en primavera archivo MultipartFile ;
file.getContentType();
fuente
Si trabaja en Linux OS, hay una línea de comando
file --mimetype
:Luego
fuente
Después de probar varias otras bibliotecas, me decidí por mime-util.
fuente
fuente
Puede hacerlo con una sola línea: MimetypesFileTypeMap (). GetContentType (nuevo archivo ("filename.ext")) . Mira el código de prueba completo (Java 7):
Este código produce el siguiente resultado: text / plain
fuente
fuente
Lo hice con el siguiente código.
fuente
Apache Tika.
y dos líneas de código.
Captura de pantalla a continuación
fuente