Obtendo o tipo MIME de um arquivo em Java

Obtendo o tipo MIME de um arquivo em Java

1. Visão geral

Neste tutorial, daremos uma olhada em várias estratégias para obter tipos MIME de um arquivo. Veremos maneiras de estender os tipos MIME disponíveis para as estratégias, sempre que aplicável.

Também apontaremos onde devemos favorecer uma estratégia em detrimento da outra.

2. Usando Java 7

Vamos começar com Java 7 - que fornece o métodoFiles.probeContentType(path) para resolver o 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 usa as implementaçõesFileTypeDetector instaladas para investigar o tipo MIME. Ele invocaprobeContentType de cada implementação para resolver o tipo.

Agora, se o arquivo for reconhecido por qualquer uma das implementações, o tipo de conteúdo será retornado. No entanto, se isso não acontecer, um detector de tipo de arquivo padrão do sistema é chamado.

No entanto, as implementações padrão são específicas do sistema operacional e podem falhar dependendo do sistema operacional que estamos usando.

Além disso, também é importante observar que a estratégia falhará se o arquivo não estiver presente no sistema de arquivos. Além disso, se o arquivo não tiver uma extensão, isso resultará em falha.

 3. UsandoURLConnection

URLConnection fornece várias APIs para detectar tipos MIME de um arquivo. Vamos explorar brevemente cada um deles.

3.1. UsandogetContentType()

Podemos usar o métodogetContentType() deURLConnection para recuperar o tipo MIME de um arquivo:

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

    assertEquals(mimeType, "image/png");
}

No entanto, uma grande desvantagem dessa abordagem é queit’s very slow.

3.2. UsandoguessContentTypeFromName()

A seguir, vamos ver como podemos usarguessContentTypeFromName() para o propósito de:

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

    assertEquals(mimeType, "image/png");
}

Este método usa oFileNameMap interno aresolve the MIME type from the extension.

Também temos a opção de usarguessContentTypeFromStream(), que usa os primeiros caracteres do fluxo de entrada, para determinar o tipo.

3.3. UsandogetFileNameMap ()

Uma maneira mais rápida de obter o tipo MIME usandoURLConnection é usar o métodogetFileNameMap():

@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");
}

O método retorna a tabela de tipos MIME usados ​​por todas as instâncias deURLConnection.. Esta tabela é então usada para resolver o tipo de arquivo de entrada.

A tabela embutida de tipos MIME é muito limitada quando se trata deURLConnection.

Por padrão, arquivothe class uses content-types.properties emJRE_HOME/lib. We can, however, extend it, by specifying a user-specific table using the content.types.user.table property:

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

4. UsandoMimeTypesFileTypeMap

MimeTypesFileTypeMap resolve os tipos MIME usando a extensão do arquivo. Essa classe veio com o Java 6 e, portanto, é muito útil quando estamos trabalhando com o JDK 1.6.

Agora vamos ver como usá-lo:

@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");
}

Aqui, podemos passar o nome do arquivo ou a própria instânciaFile como parâmetro para a função. No entanto, a função com a instânciaFile como o parâmetro chama internamente o método sobrecarregado que aceita o nome do arquivo como o parâmetro.

Internamente, este método pesquisa um arquivo chamadomime.types para a resolução de tipo. É muito importante observar que o método procura o arquivo em uma ordem específica:

  1. Entradas adicionadas programaticamente à instânciaMimetypesFileTypeMap

  2. .mime.types no diretório inicial do usuário

  3. /lib/mime.types

  4. recursos chamadosMETA-INF/mime.types

  5. recurso chamadoMETA-INF/mimetypes.default (normalmente encontrado apenas no arquivoactivation.jar)

No entanto, se nenhum arquivo for encontrado, ele retornaráapplication/octet-stream como a resposta.

5. Usando jMimeMagic

jMimeMagic é uma biblioteca com licença restrita que podemos usar para obter o tipo MIME de um arquivo.

Vamos começar configurando a dependência do Maven:


    net.sf.jmimemagic
    jmimemagic
    0.1.5

Podemos encontrar a versão mais recente desta biblioteca emMaven Central.

A seguir, exploraremos como trabalhar com a 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 pode funcionar com um fluxo de dados e, portanto, não requer que o arquivo esteja presente no sistema de arquivos.

6. Usando Apache Tika

Apache Tika é um conjunto de ferramentas que detecta e extrai metadados e texto de uma variedade de arquivos. Ele tem uma API rica e poderosa e vem comtika-core que podemos usar para detectar o tipo MIME de um arquivo.

Vamos começar configurando a dependência do Maven:


    org.apache.tika
    tika-core
    1.18

A seguir, usaremos o métododetect() para resolver o 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");
}

A biblioteca conta com marcadores mágicos no prefixo do fluxo, para resolução do tipo.

7. Conclusão

Neste artigo, vimos as várias estratégias de obtenção do tipo MIME de um arquivo. Além disso, também analisamos as vantagens e desvantagens das abordagens. Também apontamos os cenários em que devemos favorecer uma estratégia em detrimento da outra.

O código-fonte completo usado neste artigo está disponívelover at GitHub, como sempre.