Frage

Ich habe mich nur gefragt, wie die meisten Leute einen MIME-Typ aus einer Datei in Java abrufen?Bisher habe ich zwei Dienstprogramme ausprobiert: JMimeMagic & Mime-Util.

Beim ersten kam es zu Speicherausnahmen, beim zweiten wurden die Streams nicht richtig geschlossen.Ich habe mich nur gefragt, ob jemand anderes eine Methode/Bibliothek hat, die er verwendet und korrekt funktioniert?

War es hilfreich?

Lösung

In Java 7 können Sie es jetzt einfach verwenden Files.probeContentType(path).

Andere Tipps

Bedauerlicherweise,

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

funktioniert nicht, da bei dieser URL-Nutzung eine Datei gesperrt bleibt, so dass sie beispielsweise nicht mehr gelöscht werden kann.

Sie haben jedoch Folgendes:

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

und auch das Folgende, das den Vorteil hat, über die bloße Verwendung der Dateierweiterung hinauszugehen und einen Blick auf den Inhalt zu werfen

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

Allerdings ist die integrierte Tabelle der MIME-Typen, wie der obige Kommentar nahelegt, recht begrenzt und umfasst beispielsweise nicht MSWord und PDF.Wenn Sie also verallgemeinern möchten, müssen Sie über die integrierten Bibliotheken hinausgehen und beispielsweise Mime-Util verwenden (eine großartige Bibliothek, die sowohl Dateierweiterung als auch Inhalt verwendet).

Die JAF-API ist Teil von JDK 6.Ansehen javax.activation Paket.

Die interessantesten Klassen sind javax.activation.MimeType - ein tatsächlicher MIME-Typ-Inhaber - und javax.activation.MimetypesFileTypeMap – Klasse, deren Instanz den MIME-Typ als String für eine Datei auflösen kann:

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);

Mit Apache Tika Du brauchst nur drei Zeilen Code:

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

Wenn Sie eine tolle Konsole haben, fügen Sie einfach diesen Code ein und führen Sie ihn aus, um damit zu spielen:

@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)

Bedenken Sie, dass die APIs umfangreich sind und „alles“ analysieren können.Ab Tika-Core 1.14 haben Sie:

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)

Sehen die Apidoken für mehr Informationen.

Apache Tika Angebote in Tika-Kern eine Mime-Typ-Erkennung basierend auf magischen Markierungen im Stream-Präfix. tika-core ruft keine anderen Abhängigkeiten ab, wodurch es genauso leichtgewichtig ist wie das derzeit nicht verwaltete Dienstprogramm zur Mime-Typ-Erkennung.

Einfaches Codebeispiel (Java 7) unter Verwendung der Variablen theInputStream Und 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();
}

Bitte beachten Sie, dass MediaType.detect(...) nicht direkt verwendet werden kann (TIKA-1120).Weitere Hinweise finden Sie unter https://tika.apache.org/0.10/detection.html.

Wenn Sie ein Android-Entwickler sind, können Sie eine Utility-Klasse verwenden android.webkit.MimeTypeMap die MIME-Typen Dateierweiterungen zuordnet und umgekehrt.

Der folgende Codeausschnitt kann Ihnen helfen.

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

Aus Rosenindien:

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

Wenn Sie mit Java 5-6 nicht weiterkommen dann diese Dienstprogrammklasse von servoy Open-Source-Produkt.

Sie benötigen nur diese Funktion

public static String getContentType(byte[] data, String name)

Es prüft die ersten Bytes des Inhalts und gibt die Inhaltstypen basierend auf diesem Inhalt und nicht anhand der Dateierweiterung zurück.

Ich habe mich nur gefragt, wie die meisten Leute einen MIME-Typ aus einer Datei in Java abrufen?

Ich habe meine veröffentlicht SimpleMagic Java-Paket, das die Bestimmung des Inhaltstyps (Mime-Typ) aus Dateien und Byte-Arrays ermöglicht.Es dient zum Lesen und Ausführen der magischen Unix-Datei(1)-Befehlsdateien, die Teil der meisten ~Unix-Betriebssystemkonfigurationen sind.

Ich habe Apache Tika ausprobiert, aber das ist es riesig mit unzähligen Abhängigkeiten, URLConnection verwendet nicht die Bytes der Dateien und MimetypesFileTypeMap schaut sich auch nur die Dateinamen an.

Mit SimpleMagic können Sie Folgendes tun:

// 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();
}

Um mit meinen 5 Cent etwas beizutragen:

TL,DR

ich benutze MimetypesFileTypeMap und fügen Sie alle Mime, die nicht vorhanden sind und die ich speziell benötige, in die Datei mime.types ein.

Und jetzt die lange Lektüre:

Zunächst ist die Liste der MIME-Typen aufgeführt riesig, siehe hier: https://www.iana.org/assignments/media-types/media-types.xhtml

Ich nutze zunächst gerne die von JDK bereitgestellten Standardfunktionen, und wenn das nicht funktioniert, suche ich nach etwas anderem.

Bestimmen Sie den Dateityp anhand der Dateierweiterung

Seit 1.6 verfügt Java über MimetypesFileTypeMap, wie in einer der obigen Antworten erwähnt, und es ist die einfachste Möglichkeit, den MIME-Typ zu bestimmen:

new MimetypesFileTypeMap().getContentType( fileName );

In der Vanilla-Implementierung bewirkt dies nicht viel (d. h.es funktioniert für .html, aber nicht für .png).Es ist jedoch ganz einfach, jeden gewünschten Inhaltstyp hinzuzufügen:

  1. Erstellen Sie eine Datei mit dem Namen „mime.types“ im META-INF-Ordner Ihres Projekts
  2. Fügen Sie eine Zeile für jeden Mime-Typ hinzu, den Sie benötigen und der in der Standardimplementierung nicht bereitgestellt wird (es gibt Hunderte von Mime-Typen und die Liste wächst mit der Zeit).

Beispieleinträge für PNG- und JS-Dateien wären:

image/png png PNG
application/javascript js

Weitere Informationen zum mime.types-Dateiformat finden Sie hier: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html

Bestimmen Sie den Dateityp anhand des Dateiinhalts

Seit 1.7 hat Java java.nio.file.spi.FileTypeDetector, die eine Standard-API zum Bestimmen eines Dateityps in definiert umsetzungsspezifische Art und Weise.

Um den MIME-Typ für eine Datei abzurufen, verwenden Sie einfach Dateien und tun Sie dies in Ihrem Code:

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

Die API-Definition sieht Funktionen vor, die entweder die Bestimmung des Datei-MIME-Typs anhand des Dateinamens oder des Dateiinhalts (magische Bytes) unterstützen.Darum probeContentType() Die Methode löst eine IOException aus, falls eine Implementierung dieser API den ihr bereitgestellten Pfad verwendet, um tatsächlich zu versuchen, die damit verbundene Datei zu öffnen.

Wieder Vanille Implementierung davon (das, das mit JDK geliefert wird) lässt viel zu wünschen übrig.

In einer idealen Welt in einer weit, weit entfernten Galaxie würden alle diese Bibliotheken, die versuchen, dieses File-to-Mime-Type-Problem zu lösen, einfach implementiert java.nio.file.spi.FileTypeDetector, würden Sie die JAR-Datei der bevorzugten implementierenden Bibliothek in Ihren Klassenpfad einfügen und das wäre es.

In der realen Welt, in der Sie den Abschnitt TL, DR benötigen, sollten Sie die Bibliothek mit den meisten Sternen neben ihrem Namen finden und sie verwenden.Für diesen speziellen Fall benötige ich (noch) keins ;) ).

Ich habe mehrere Möglichkeiten ausprobiert, darunter auch die ersten von @Joshua Fox.Einige erkennen jedoch häufige Mimetypen wie bei PDF-Dateien nicht und andere sind bei gefälschten Dateien nicht vertrauenswürdig (ich habe es mit einer RAR-Datei versucht, deren Erweiterung in TIF geändert wurde).Die Lösung, die ich gefunden habe, ist, wie @Joshua Fox auch oberflächlich sagt, die Verwendung MimeUtil2, so was:

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

Es ist besser, für das Hochladen von Dateien eine zweistufige Validierung zu verwenden.

Zuerst können Sie nach dem mimeType suchen und ihn validieren.

Zweitens sollten Sie versuchen, die ersten 4 Bytes Ihrer Datei in Hexadezimalzahlen umzuwandeln und sie dann mit den magischen Zahlen zu vergleichen.Dann ist es eine wirklich sichere Möglichkeit, nach Dateivalidierungen zu suchen.

im Frühling MultipartFile Datei;

org.springframework.web.multipart.MultipartFile

file.getContentType();

Dies ist der einfachste Weg, den ich dafür gefunden habe:

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

Wenn Sie unter Linux arbeiten, gibt es eine Befehlszeile 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 "";
}

Dann

mimetype("/home/nyapp.war") //  'application/zip'

mimetype("/var/www/ggg/au.mp3") //  'audio/mp3'

Nachdem ich verschiedene andere Bibliotheken ausprobiert hatte, entschied ich mich für 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);
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;
}

Sie können es mit nur einer Zeile tun: MimetypesFileTypeMap().getContentType(new File("filename.ext")).Sehen Sie sich den vollständigen Testcode (Java 7) an:

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

Dieser Code erzeugt die folgende Ausgabe: Text/einfach

File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top