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);
En Java 7 ahora puedes usar Files.probeContentType(path)
.
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:
- Cree un archivo llamado ''mime.types'' en la carpeta META-INF en su proyecto
- 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 .
Si está atascado con Java 5-6, entonces esta clase de utilidad del https://github.com/Servoy/servoy-client/blob/e7f5bce3c3dc0f0eb1cd240fce48c75143a25432/servoy_shared/src/com/servoy/j2db/util/MimeTypes.java#L34 .
Solo necesitas esta función.
public static String getContentType(byte[] data, String name)
Sondea los primeros bytes del contenido y devuelve los tipos de contenido basados en ese contenido y no por extensión de archivo.
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;
}