Obtener el tipo Mime de un archivo en Java

1. Información general

En este tutorial, veremos varias estrategias para obtener tipos MIME de un archivo. Buscaremos formas de extender los tipos MIME disponibles para las estrategias, donde sea aplicable.

También señalaremos dónde deberíamos favorecer una estrategia sobre la otra.

2. Usando Java 7

Comencemos con Java 7, que proporciona el método Files.probeContentType (ruta) para resolver el tipo MIME:

@Test public void whenUsingJava7_thenSuccess() { Path path = new File("product.png").toPath(); String mimeType = Files.probeContentType(path); assertEquals(mimeType, "image/png"); } 

Este método hace uso de las implementaciones de FileTypeDetector instaladas para probar el tipo MIME. Invoca probeContentType de cada implementación para resolver el tipo.

Ahora, si el archivo es reconocido por cualquiera de las implementaciones, se devuelve el tipo de contenido. Sin embargo, si eso no sucede, se invoca un detector de tipo de archivo predeterminado del sistema.

Sin embargo, las implementaciones predeterminadas son específicas del sistema operativo y pueden fallar según el sistema operativo que estemos usando.

Además de eso, también es importante tener en cuenta que la estrategia fallará si el archivo no está presente en el sistema de archivos. Además, si el archivo no tiene extensión, fallará.

3. Usando URLConnection

URLConnection proporciona varias API para detectar tipos MIME de un archivo. Exploremos brevemente cada uno de ellos.

3.1. Usando getContentType ()

Podemos usar el método getContentType () de URLConnection para recuperar el tipo MIME de un archivo:

@Test public void whenUsingGetContentType_thenSuccess(){ File file = new File("product.png"); URLConnection connection = file.toURL().openConnection(); String mimeType = connection.getContentType(); assertEquals(mimeType, "image/png"); }

Sin embargo, un gran inconveniente de este enfoque es que es muy lento .

3.2. Usando guessContentTypeFromName ()

A continuación, veamos cómo podemos hacer uso de guessContentTypeFromName () para este propósito:

@Test public void whenUsingGuessContentTypeFromName_thenSuccess(){ File file = new File("product.png"); String mimeType = URLConnection.guessContentTypeFromName(file.getName()); assertEquals(mimeType, "image/png"); }

Este método utiliza el FileNameMap interno para resolver el tipo MIME de la extensión .

También tenemos la opción de usar guessContentTypeFromStream () en su lugar, que usa los primeros caracteres del flujo de entrada, para determinar el tipo.

3.3. Usando getFileNameMap ()

Una forma más rápida de obtener el tipo MIME usando URLConnection es usando el método getFileNameMap () :

@Test public void whenUsingGetFileNameMap_thenSuccess(){ File file = new File("product.png"); FileNameMap fileNameMap = URLConnection.getFileNameMap(); String mimeType = fileNameMap.getContentTypeFor(file.getName()); assertEquals(mimeType, "image/png"); }

El método devuelve la tabla de tipos MIME utilizados por todas las instancias de URLConnection. Esta tabla luego se usa para resolver el tipo de archivo de entrada.

La tabla incorporada de tipos MIME es muy limitada cuando se trata de URLConnection .

Por defecto, los usos de clase content-types.properties archivo en JRE_HOME / lib . Sin embargo, podemos ampliarlo especificando una tabla específica del usuario utilizando la propiedad content.types.user.table :

System.setProperty("content.types.user.table",""); 

4. Uso de MimeTypesFileTypeMap

MimeTypesFileTypeMap resuelve los tipos MIME mediante la extensión del archivo. Esta clase vino con Java 6 y, por lo tanto, es muy útil cuando trabajamos con JDK 1.6.

Ahora veamos cómo usarlo:

@Test public void whenUsingMimeTypesFileTypeMap_thenSuccess() { File file = new File("product.png"); MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap(); String mimeType = fileTypeMap.getContentType(file.getName()); assertEquals(mimeType, "image/png"); }

Aquí, podemos pasar el nombre del archivo o la propia instancia del Archivo como parámetro de la función. Sin embargo, la función con la instancia de Archivo como parámetro llama internamente al método sobrecargado que acepta el nombre de archivo como parámetro.

Internamente, este método busca un archivo llamado mime.types para la resolución de tipos. Es muy importante tener en cuenta que el método busca el archivo en un orden específico:

  1. Entradas agregadas mediante programación a la instancia de MimetypesFileTypeMap
  2. . mime.types en el directorio de inicio del usuario
  3. /lib/mime.types
  4. recursos denominados META-INF / mime.types
  5. recurso llamado META-INF / mimetypes.default (generalmente se encuentra solo en el archivo activación.jar )

Sin embargo, si no se encuentra ningún archivo, devolverá application / octet-stream como respuesta.

5. Usando jMimeMagic

jMimeMagic es una biblioteca con licencia restrictiva que podemos usar para obtener el tipo MIME de un archivo.

Comencemos configurando la dependencia de Maven:

 net.sf.jmimemagic jmimemagic 0.1.5 

Podemos encontrar la última versión de esta biblioteca en Maven Central.

A continuación, exploraremos cómo trabajar con la biblioteca:

@Test public void whenUsingJmimeMagic_thenSuccess() { File file = new File("product.png"); Magic magic = new Magic(); MagicMatch match = magic.getMagicMatch(file, false); assertEquals(match.getMimeType(), "image/png"); }

Esta biblioteca puede funcionar con un flujo de datos y, por lo tanto, no requiere que el archivo esté presente en el sistema de archivos.

6. Usando Apache Tika

Apache Tika es un conjunto de herramientas que detecta y extrae metadatos y texto de una variedad de archivos. Tiene una API rica y poderosa y viene con tika-core que podemos utilizar para detectar el tipo MIME de un archivo.

Comencemos configurando la dependencia de Maven:

 org.apache.tika tika-core 1.18 

A continuación, usaremos el método detect () para resolver el tipo:

@Test public void whenUsingTika_thenSuccess() { File file = new File("product.png"); Tika tika = new Tika(); String mimeType = tika.detect(file); assertEquals(mimeType, "image/png"); }

La biblioteca se basa en marcadores mágicos en el prefijo de flujo para la resolución de tipos.

7. Conclusión

En este artículo, hemos analizado las diversas estrategias para obtener el tipo MIME de un archivo. Además, también hemos analizado las compensaciones de los enfoques. También hemos señalado los escenarios en los que deberíamos favorecer una estrategia sobre la otra.

El código fuente completo que se utiliza en este artículo está disponible en GitHub, como siempre.