Zastanawiałem się, jak większość ludzi pobiera typ MIME z pliku w Javie? Do tej pory wypróbowałem dwa narzędzia: JMimeMagic
& Mime-Util
.
Pierwszy dał mi wyjątki pamięci, drugi nie zamyka poprawnie swoich strumieni. Zastanawiałem się tylko, czy ktoś miał metodę / bibliotekę, której używał i działał poprawnie?
Odpowiedzi:
W Javie 7 możesz teraz po prostu używać
Files.probeContentType(path)
.źródło
null
się do.xml
,.png
i.xhtml
plików. Nie wiem, czy robię coś okropnie złego, ale wydaje się to dość okropne.Niestety,
nie działa, ponieważ takie użycie adresu URL pozostawia plik zablokowany, więc na przykład nie można go usunąć.
Masz jednak:
a także następujące, które mają tę zaletę, że wykraczają poza zwykłe korzystanie z rozszerzenia pliku i zerkają na treść
Jednak, jak sugeruje powyższy komentarz, wbudowana tabela typów mime jest dość ograniczona, nie obejmuje na przykład MSWord i PDF. Jeśli chcesz uogólnić, musisz wyjść poza wbudowane biblioteki, używając np. Mime-Util (która jest świetną biblioteką, wykorzystującą zarówno rozszerzenie pliku, jak i zawartość).
źródło
FileInputStream
sięBufferedInputStream
jest kluczowym elementem - w przeciwnym razieguessContentTypeFromStream
powrócinull
(przeszedłInputStream
instancja powinna wspierać znaków)URLConnection
ma bardzo ograniczony zestaw typów treści, które rozpoznaje. Na przykład nie jest w stanie wykryćapplication/pdf
.guessContentTypeFromName()
używa$JAVA_HOME/lib/content-types.properties
pliku domyślnego . możesz dodać własny rozszerzony plik, zmieniając właściwość systemuSystem.setProperty("content.types.user.table","/lib/path/to/your/property/file");
Interfejs API JAF jest częścią JDK 6. Spójrz na
javax.activation
pakiet.Najbardziej interesujące klasy to
javax.activation.MimeType
- faktyczny posiadacz typu MIME - ijavax.activation.MimetypesFileTypeMap
- klasa, której instancja może rozpoznać typ MIME jako ciąg znaków dla pliku:źródło
getContentType(File)
stanów: Zwraca typ MIME obiektu pliku. Implementacja w tej klasie wywołujegetContentType(f.getName())
.MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file)
Z Apache Tika potrzebujesz tylko trzech linii kodu :
Jeśli masz świetną konsolę, po prostu wklej i uruchom ten kod, aby się nim bawić:
Należy pamiętać, że jego interfejsy API są bogate, może analizować „wszystko”. Od wersji 1.14 tika-core masz:
Zobacz apidocs, aby uzyskać więcej informacji.
źródło
new Tika().detect(file.toPath())
wykrywanie oparte na rozszerzeniu pliku zamiast wykrywanie oparte na zawartości plikunew Tika().detect(file.getPath())
, który używa tylko rozszerzenia plikuApache Tika oferuje w tika-core wykrywanie typu mime oparte na magicznych znacznikach w prefiksie strumienia.
tika-core
nie pobiera innych zależności, co czyni go tak lekkim, jak obecnie nieobsługiwane narzędzie do wykrywania typu Mime .Prosty przykład kodu (Java 7), przy użyciu zmiennych
theInputStream
itheFileName
Należy pamiętać, że MediaType.detect (...) nie można używać bezpośrednio ( TIKA-1120 ). Więcej wskazówek można znaleźć na stronie https://tika.apache.org/0.10/detection.html .
źródło
Metadata.RESOURCE_NAME_KEY
Można również pominąć (jeśli nie masz lub nie możesz polegać na oryginalnej nazwie), ale w takim przypadku w niektórych przypadkach otrzymasz błędny wynik (na przykład dokumenty biurowe).Jeśli jesteś programistą Androida, możesz użyć klasy narzędzia,
android.webkit.MimeTypeMap
która mapuje typy MIME na rozszerzenia plików i odwrotnie.Poniższy fragment kodu może ci pomóc.
źródło
Z roseindii :
źródło
Jeśli utkniesz z javą 5-6, to ta klasa narzędziowa z serwomechanizmu produktu open source .
Potrzebujesz tylko tej funkcji
Sprawdza pierwsze bajty zawartości i zwraca typy zawartości na podstawie tej zawartości, a nie według rozszerzenia pliku.
źródło
Opublikowałem mój pakiet Java SimpleMagic , który umożliwia określanie typu zawartości (typu MIME) na podstawie plików i tablic bajtów. Jest przeznaczony do odczytu i uruchamiania magicznych plików poleceń Unix file (1), które są częścią większości ~ konfiguracji systemu operacyjnego Unix.
Próbowałem Apache Tika, ale jest ogromny z mnóstwem zależności,
URLConnection
nie używa bajtów plików, aMimetypesFileTypeMap
także tylko patrzy na nazwy plików.Dzięki SimpleMagic możesz zrobić coś takiego:
źródło
Aby włożyć moje 5 centów:
TL, DR
Korzystam z MimetypesFileTypeMap i dodam każdy mime, którego nie ma, a szczególnie go potrzebuję, do pliku mime.types.
A teraz długo czytam:
Przede wszystkim lista typów MIME jest ogromna , patrz tutaj: https://www.iana.org/assignments/media-types/media-types.xhtml
Najpierw lubię korzystać ze standardowych udogodnień dostarczonych przez JDK, a jeśli to nie zadziała, pójdę poszukać czegoś innego.
Określ typ pliku na podstawie rozszerzenia pliku
Od wersji 1.6 Java ma MimetypesFileTypeMap, jak wskazano w jednej z powyższych odpowiedzi, i jest to najprostszy sposób na określenie typu MIME:
W swojej waniliowej implementacji nie robi to wiele (tj. Działa na .html, ale nie działa na .png). Jednak bardzo łatwo jest dodać dowolny typ zawartości, który może być potrzebny:
Przykładowe wpisy dla plików png i js to:
Aby uzyskać informacje na temat formatu pliku mime.types, zobacz więcej szczegółów tutaj: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html
Określ typ pliku na podstawie zawartości pliku
Od wersji 1.7 Java ma java.nio.file.spi.FileTypeDetector , który definiuje standardowy interfejs API do określania typu pliku w sposób specyficzny dla implementacji .
Aby pobrać typ MIME dla pliku, wystarczy użyć Pliki i zrobić to w kodzie:
Definicja API zapewnia funkcje, które obsługują określanie typu MIME pliku na podstawie nazwy pliku lub zawartości pliku (bajty magiczne). Dlatego metoda probeContentType () zgłasza wyjątek IOException w przypadku, gdy implementacja tego interfejsu API używa podanej do niego ścieżki do faktycznego otwarcia pliku z nim powiązanego.
Ponownie, waniliowa implementacja tego (tego, który jest dostarczany z JDK) pozostawia wiele do życzenia.
W jakimś idealnym świecie w odległej galaktyce, wszystkie te biblioteki, które próbują rozwiązać ten problem typu „plik do mima”, po prostu zaimplementowałyby java.nio.file.spi.FileTypeDetector , upuściłbyś słoik preferowanej biblioteki implementującej plik do ścieżki klasy i to by było na tyle.
W prawdziwym świecie, w którym potrzebujesz sekcji TL, DR, powinieneś znaleźć bibliotekę z większością gwiazdek obok jej nazwy i użyć jej. W tym konkretnym przypadku nie potrzebuję (jeszcze;)).
źródło
Próbowałem tego dokonać na kilka sposobów, w tym pierwsze wypowiedziane przez @Joshua Fox. Ale niektórzy nie rozpoznają częstych typów mimetycznych, takich jak pliki PDF, a innym nie można ufać fałszywym plikom (próbowałem z plikiem RAR z rozszerzeniem zmienionym na TIF). Rozwiązaniem, które znalazłem, jak również powierzchownie powiedział @Joshua Fox, jest użycie MimeUtil2 w następujący sposób:
źródło
Lepiej jest użyć weryfikacji dwuwarstwowej do przesyłania plików.
Najpierw możesz sprawdzić mimeType i zweryfikować go.
Po drugie, powinieneś przekonwertować pierwsze 4 bajty pliku na szesnastkowy, a następnie porównać go z liczbami magicznymi. Będzie to naprawdę bezpieczny sposób sprawdzania poprawności plików.
źródło
Oto najprostszy sposób na zrobienie tego:
źródło
Jeśli pracujesz z serwletem i jeśli kontekst serwletu jest dostępny, możesz użyć:
źródło
getServletContext
?wiosną plik MultipartFile ;
file.getContentType();
źródło
jeśli pracujesz na systemie operacyjnym Linux, istnieje linia poleceń
file --mimetype
:Następnie
źródło
Po wypróbowaniu różnych innych bibliotek zdecydowałem się na mime-util.
źródło
źródło
Możesz to zrobić za pomocą tylko jednej linii: MimetypesFileTypeMap (). GetContentType (nowy plik („nazwa_pliku.ext”)) . Spójrz na pełny kod testowy (Java 7):
Ten kod generuje następujące dane wyjściowe: tekst / zwykły
źródło
źródło
Zrobiłem to z następującym kodem.
źródło
Apache Tika.
i dwie linie kodu.
Zrzut ekranu poniżej
źródło