type que octet getcontenttype from example application java mime

que - mime type java example



Obtener el tipo Mime de un archivo en Java (18)

Me preguntaba cómo la mayoría de las personas obtienen un tipo mime de un archivo en Java. Hasta ahora he probado dos utils: JMimeMagic y Mime-Util .

El primero me dio excepciones de memoria, el segundo no cierra sus flujos correctamente. Me preguntaba si alguien más tenía un método / biblioteca que utilizaron y funcionaron correctamente.


Me preguntaba cómo la mayoría de las personas obtienen un tipo mime de un archivo en Java.

He publicado mi paquete Java SimpleMagic que permite la determinación del tipo de contenido (tipo mime) a partir de archivos y matrices de bytes. Está diseñado para leer y ejecutar el archivo Unix (1) comando archivos mágicos que son parte de la mayoría de las configuraciones de ~ SO Unix.

Intenté Apache Tika pero es enorme con un montón de dependencias, URLConnection no usa los bytes de los archivos y MimetypesFileTypeMap también solo mira los nombres de los archivos.

Con SimpleMagic puedes hacer algo como:

// create a magic utility using the internal magic file ContentInfoUtil util = new ContentInfoUtil(); // if you want to use a different config file(s), you can load them by hand: // ContentInfoUtil util = new ContentInfoUtil("/etc/magic"); ... ContentInfo info = util.findMatch("/tmp/upload.tmp"); // or ContentInfo info = util.findMatch(inputStream); // or ContentInfo info = util.findMatch(contentByteArray); // null if no match if (info != null) { String mimeType = info.getMimeType(); }


Con Apache Tika solo necesitas tres líneas de código :

File file = new File("/path/to/file"); Tika tika = new Tika(); System.out.println(tika.detect(file));

Si tienes una consola genial, simplemente pega y ejecuta este código para jugar con ella:

@Grab(''org.apache.tika:tika-core:1.14'') import org.apache.tika.Tika; def tika = new Tika() def file = new File("/path/to/file") println tika.detect(file)

Tenga en cuenta que sus API son ricas, puede analizar "cualquier cosa". A partir de tika-core 1.14, tienes:

String detect(byte[] prefix) String detect(byte[] prefix, String name) String detect(File file) String detect(InputStream stream) String detect(InputStream stream, Metadata metadata) String detect(InputStream stream, String name) String detect(Path path) String detect(String name) String detect(URL url)

Ver los apidocs para más información.


De roseindia :

FileNameMap fileNameMap = URLConnection.getFileNameMap(); String mimeType = fileNameMap.getContentTypeFor("alert.gif");


Desafortunadamente,

mimeType = file.toURL().openConnection().getContentType();

no funciona, ya que este uso de la URL deja un archivo bloqueado, por lo que, por ejemplo, no se puede recuperar.

Sin embargo, tienes esto:

mimeType= URLConnection.guessContentTypeFromName(file.getName());

y también lo siguiente, que tiene la ventaja de ir más allá del simple uso de la extensión de archivo, y echa un vistazo al contenido

InputStream is = new BufferedInputStream(new FileInputStream(file)); mimeType = URLConnection.guessContentTypeFromStream(is); //...close stream

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 usa tanto la extensión de archivo como el contenido).


Después de probar varias otras bibliotecas me instalé con mime-util.

<groupId>eu.medsea.mimeutil</groupId> <artifactId>mime-util</artifactId> <version>2.1.3</version> </dependency> File file = new File("D:/test.tif"); MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector"); Collection<?> mimeTypes = MimeUtil.getMimeTypes(file); System.out.println(mimeTypes);



Es mejor usar la validación de dos capas para subir archivos.

Primero puedes verificar el mimeType y validarlo.

En segundo lugar, debes buscar convertir los primeros 4 bytes de tu archivo a hexadecimal y luego compararlos con los números mágicos. Entonces será una forma realmente segura de verificar las validaciones de archivos.


Esta es la forma más simple que encontré para hacer esto:

byte[] byteArray = ... InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray)); String mimeType = URLConnection.guessContentTypeFromStream(is);


La API de JAF es parte de JDK 6. Mire el paquete javax.activation .

Las clases más interesantes son javax.activation.MimeType - un titular de tipo MIME real - y javax.activation.MimetypesFileTypeMap - clase cuya instancia puede resolver el tipo MIME como una cadena para un archivo:

String fileName = "/path/to/file"; MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); // only by file name String mimeType = mimeTypesMap.getContentType(fileName); // or by actual File instance File file = new File(fileName); mimeType = mimeTypesMap.getContentType(file);


Para entrar con mis 5 centavos:

TL, DR

Uso MimetypesFileTypeMap y agrego cualquier mime que no esté allí y específicamente lo necesito, 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 primero las instalaciones estándar proporcionadas por JDK, y si eso no funciona, buscaré otra cosa.

Determine el tipo de archivo de la extensión de archivo

Desde 1.6, Java tiene MimetypesFileTypeMap, como se señaló en una de las respuestas anteriores, y es la forma más sencilla de determinar el tipo mime:

new MimetypesFileTypeMap().getContentType( fileName );

En su implementación de vainilla esto no hace mucho (es decir, funciona para .html pero no para .png). Sin embargo, es muy sencillo agregar cualquier tipo de contenido que pueda necesitar:

  1. Cree un archivo llamado ''mime.types'' en la carpeta META-INF en su proyecto
  2. Agregue una línea para cada tipo de mime que necesite y la implementación predeterminada no se proporcione (hay cientos de tipos de mime y la lista crece a medida que pasa el tiempo).

Las entradas de ejemplo para los archivos png y js serían:

image/png png PNG application/javascript js

Para el formato de archivo mime.types, vea más detalles aquí: MimetypesFileTypeMap

Determinar el tipo de archivo a partir del contenido del archivo

Desde la java.nio.file.spi.FileTypeDetector 1.7, Java tiene java.nio.file.spi.FileTypeDetector , que define una API estándar para determinar un tipo de archivo de manera específica a la implementación .

Para obtener el tipo de mime para un archivo, simplemente usaría Files y haría esto en su código:

Files.probeContentType(Paths.get("either file name or full path goes here"));

La definición de la 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 probeContentType() método probeContentType() lanza la excepción IOException, en caso de que una implementación de esta API use la Ruta provista para tratar de abrir el archivo asociado.

Una vez más, la implementación de este tipo (la que viene con JDK) deja mucho que desear.

En un mundo ideal en una galaxia muy, muy lejos, todas estas bibliotecas que intentan resolver este problema de tipo de archivo a mimo simplemente implementarían java.nio.file.spi.FileTypeDetector , colocarías en el jar de la biblioteca de implementación preferida archivo en tu classpath y eso sería todo.

En el mundo real, en el que necesita TL, sección DR, debe encontrar la biblioteca con la mayoría de las estrellas junto a su nombre y usarla. Para este caso en particular, no necesito uno (todavía;)).


Probé varias formas de hacerlo, incluyendo las primeras que dijo @Joshua Fox. Pero algunos no reconocen tipos de mimo frecuentes como los archivos PDF, y otros no pueden ser confiables con archivos falsos (probé con un archivo RAR con la extensión cambiada a TIF). La solución que encontré, como también lo dice @Joshua Fox de manera superficial, es usar MimeUtil2 , así:

MimeUtil2 mimeUtil = new MimeUtil2(); mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector"); String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();


Puede hacerlo con una sola línea: MimetypesFileTypeMap (). GetContentType (nuevo archivo ("filename.ext")) . Mira el código de prueba completo (Java 7):

import java.io.File; import javax.activation.MimetypesFileTypeMap; public class MimeTest { public static void main(String a[]){ System.out.println(new MimetypesFileTypeMap().getContentType( new File("/path/filename.txt"))); } }

Este código produce el siguiente resultado: texto / plano


Si eres un desarrollador de Android, puedes 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 ayudarte.

private static String getMimeType(String fileUrl) { String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl); return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); }


Si trabaja en Linux OS, hay un file --mimetype línea de file --mimetype :

String mimetype(file){ //1. run cmd Object cmd=Runtime.getRuntime().exec("file --mime-type "+file); //2 get output of cmd , then //3. parse mimetype if(output){return output.split(":")[1].trim(); } return ""; }

Entonces

mimetype("/home/nyapp.war") // ''application/zip'' mimetype("/var/www/ggg/au.mp3") // ''audio/mp3''


en el archivo MultipartFile de primavera;

org.springframework.web.multipart.MultipartFile

file.getContentType();


Apache Tika ofrece en tika-core una detección de tipo mime basada en marcadores mágicos en el prefijo de flujo. tika-core no recupera otras dependencias, lo que lo hace tan liviano como la utilidad de detección de tipo Mime que actualmente no se mantiene.

Ejemplo de código simple (Java 7), utilizando las variables theInputStream y theFileName

try (InputStream is = theInputStream; BufferedInputStream bis = new BufferedInputStream(is);) { AutoDetectParser parser = new AutoDetectParser(); Detector detector = parser.getDetector(); Metadata md = new Metadata(); md.add(Metadata.RESOURCE_NAME_KEY, theFileName); MediaType mediaType = detector.detect(bis, md); return mediaType.toString(); }

Tenga en cuenta que MediaType.detect (...) no se puede utilizar directamente ( TIKA-1120 ). Se proporcionan más sugerencias en https://tika.apache.org/0.10/detection.html .



public String getFileContentType(String fileName) { String fileType = "Undetermined"; final File file = new File(fileName); try { fileType = Files.probeContentType(file.toPath()); } catch (IOException ioException) { System.out.println( "ERROR: Unable to determine file type for " + fileName + " due to exception " + ioException); } return fileType; }