<p>How do you get a Media Type (MIME type) from a file using Java?  So far I've tried JMimeMagic &amp; Mime-Util. The first gave me memory exceptions, the second doesn't close its streams properly.</p>
<p>How would you probe the file to determine its actual type (not merely based on the extension)?</p>

[{'answer_id': 847849, 'author': 'Joshua Fox', 'author_id': 39242, 'author_profile': 'https://Stackoverflow.com/users/39242', 'pm_score': 8, 'selected': False, 'text': "<p>Unfortunately,</p>\n\n<pre><code>mimeType = file.toURL().openConnection().getContentType();\n</code></pre>\n\n<p>does not work, since this use of URL leaves a file locked, so that, for example, it is undeletable.</p>\n\n<p>However, you have this:</p>\n\n<pre><code>mimeType= URLConnection.guessContentTypeFromName(file.getName());\n</code></pre>\n\n<p>and also the following, which has the advantage of going beyond mere use of file extension, and takes  a peek at content</p>\n\n<pre><code>InputStream is = new BufferedInputStream(new FileInputStream(file));\nmimeType = URLConnection.guessContentTypeFromStream(is);\n //...close stream\n</code></pre>\n\n<p>However, as suggested by the comment above, the built-in table of mime-types is quite limited, not including, for example, MSWord and PDF. So, if you want to generalize, you'll need to go beyond the built-in libraries, using, e.g., Mime-Util (which is a great library, using both file extension and content).</p>\n"}, {'answer_id': 1902146, 'author': 'Adam Hošek', 'author_id': 157423, 'author_profile': 'https://Stackoverflow.com/users/157423', 'pm_score': 6, 'selected': False, 'text': '<p>The JAF API is part of JDK 6. Look at <code>javax.activation</code> package.</p>\n\n<p>Most interesting classes are <code>javax.activation.MimeType</code> - an actual MIME type holder - and <code>javax.activation.MimetypesFileTypeMap</code> - class whose instance can resolve MIME type as String for a file:</p>\n\n<pre><code>String fileName = "/path/to/file";\nMimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();\n\n// only by file name\nString mimeType = mimeTypesMap.getContentType(fileName);\n\n// or by actual File instance\nFile file = new File(fileName);\nmimeType = mimeTypesMap.getContentType(file);\n</code></pre>\n'}, {'answer_id': 6899179, 'author': 'AlikElzin-kilaka', 'author_id': 435605, 'author_profile': 'https://Stackoverflow.com/users/435605', 'pm_score': 4, 'selected': False, 'text': '<p>From <a href="http://www.roseindia.net/java/java-get-example/get-mime-type.shtml">roseindia</a>:</p>\n\n<pre><code>FileNameMap fileNameMap = URLConnection.getFileNameMap();\nString mimeType = fileNameMap.getContentTypeFor("alert.gif");\n</code></pre>\n'}, {'answer_id': 8973468, 'author': 'Chris Mowforth', 'author_id': 468112, 'author_profile': 'https://Stackoverflow.com/users/468112', 'pm_score': 9, 'selected': True, 'text': '<p>In Java 7 you can now just use <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType%28java.nio.file.Path%29" rel="noreferrer"><code>Files.probeContentType(path)</code></a>.</p>\n'}, {'answer_id': 12534954, 'author': 'ricardoc', 'author_id': 1126309, 'author_profile': 'https://Stackoverflow.com/users/1126309', 'pm_score': 2, 'selected': False, 'text': '<p>I tried several ways to do it, including the first ones said by @Joshua Fox. But some don\'t recognize frequent mimetypes like for PDF files, and other could not be trustable with fake files (I tried with a RAR file with extension changed to TIF). The solution I found, as also is said by @Joshua Fox in a superficial way, is to use <a href="https://mvnrepository.com/artifact/eu.medsea.mimeutil/mime-util/2.1.2" rel="nofollow noreferrer">MimeUtil2</a>, like this:</p>\n\n<pre><code>MimeUtil2 mimeUtil = new MimeUtil2();\nmimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");\nString mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();\n</code></pre>\n'}, {'answer_id': 13889946, 'author': 'Pawan', 'author_id': 1365340, 'author_profile': 'https://Stackoverflow.com/users/1365340', 'pm_score': 5, 'selected': False, 'text': "<p>If you're an Android developer, you can use a utility class <code>android.webkit.MimeTypeMap</code> which maps MIME-types to file extensions and vice versa. <p> Following code snippet may help you.</p>\n\n<pre><code>private static String getMimeType(String fileUrl) {\n    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);\n    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);\n}\n</code></pre>\n"}, {'answer_id': 16626396, 'author': 'koppor', 'author_id': 873282, 'author_profile': 'https://Stackoverflow.com/users/873282', 'pm_score': 5, 'selected': False, 'text': '<p><a href="https://tika.apache.org/" rel="nofollow noreferrer">Apache Tika</a> offers in <a href="https://search.maven.org/artifact/org.apache.tika/tika-core" rel="nofollow noreferrer">tika-core</a> a mime type detection based based on magic markers in the stream prefix. <code>tika-core</code> does not fetch other dependencies, which makes it as lightweight as the currently unmaintained <a href="http://sourceforge.net/projects/mime-util/" rel="nofollow noreferrer">Mime Type Detection Utility</a>.</p>\n<p>Simple code example (Java 7), using the variables <code>theInputStream</code> and <code>theFileName</code></p>\n<pre><code>try (InputStream is = theInputStream;\n        BufferedInputStream bis = new BufferedInputStream(is);) {\n    AutoDetectParser parser = new AutoDetectParser();\n    Detector detector = parser.getDetector();\n    Metadata md = new Metadata();\n    md.add(Metadata.RESOURCE_NAME_KEY, theFileName);\n    MediaType mediaType = detector.detect(bis, md);\n    return mediaType.toString();\n}\n</code></pre>\n<p>Please note that <code>MediaType.detect(...)</code> cannot be used directly (<a href="https://issues.apache.org/jira/browse/TIKA-1120" rel="nofollow noreferrer">TIKA-1120</a>). More hints are provided at <a href="https://tika.apache.org/1.24/detection.html" rel="nofollow noreferrer">https://tika.apache.org/1.24/detection.html</a>.</p>\n'}, {'answer_id': 17302243, 'author': 'Gray', 'author_id': 179850, 'author_profile': 'https://Stackoverflow.com/users/179850', 'pm_score': 4, 'selected': False, 'text': '<blockquote>\n  <p>I was just wondering how most people fetch a mime type from a file in Java? </p>\n</blockquote>\n\n<p>I\'ve published my <a href="http://256stuff.com/sources/simplemagic/" rel="noreferrer">SimpleMagic</a> Java package which allows content-type (mime-type) determination from files and byte arrays. It is designed to read and run the Unix file(1) command magic files that are a part of most ~Unix OS configurations.</p>\n\n<p>I tried Apache Tika but it is <em>huge</em> with tons of dependencies, <code>URLConnection</code> doesn\'t use the bytes of the files, and <code>MimetypesFileTypeMap</code> also just looks at files names.</p>\n\n<p>With SimpleMagic you can do something like:</p>\n\n<pre><code>// create a magic utility using the internal magic file\nContentInfoUtil util = new ContentInfoUtil();\n// if you want to use a different config file(s), you can load them by hand:\n// ContentInfoUtil util = new ContentInfoUtil("/etc/magic");\n...\nContentInfo info = util.findMatch("/tmp/upload.tmp");\n// or\nContentInfo info = util.findMatch(inputStream);\n// or\nContentInfo info = util.findMatch(contentByteArray);\n\n// null if no match\nif (info != null) {\n   String mimeType = info.getMimeType();\n}\n</code></pre>\n'}, {'answer_id': 18640199, 'author': 'Ovidiu Buligan', 'author_id': 284314, 'author_profile': 'https://Stackoverflow.com/users/284314', 'pm_score': 4, 'selected': False, 'text': '<p><strong>If you are stuck with java 5-6</strong> then this utility class from <a href="https://github.com/Servoy/servoy-client/blob/e7f5bce3c3dc0f0eb1cd240fce48c75143a25432/servoy_shared/src/com/servoy/j2db/util/MimeTypes.java#L34" rel="nofollow noreferrer">servoy open source product</a>.</p>\n\n<p>You only need this function </p>\n\n<pre><code>public static String getContentType(byte[] data, String name)\n</code></pre>\n\n<p>It probes the first bytes of the content and returns the content types based on that content and not by file extension.</p>\n'}, {'answer_id': 25379881, 'author': 'javacreed', 'author_id': 2089557, 'author_profile': 'https://Stackoverflow.com/users/2089557', 'pm_score': 2, 'selected': False, 'text': '<p>It is better to use two layer validation for files upload. </p>\n\n<p>First you can check for the mimeType and validate it. </p>\n\n<p>Second you should look to convert the first 4 bytes of your file to hexadecimal and then compare it with the magic numbers. Then it will be a really secure way to check for file validations.</p>\n'}, {'answer_id': 27342079, 'author': 'Abdennour TOUMI', 'author_id': 747579, 'author_profile': 'https://Stackoverflow.com/users/747579', 'pm_score': 0, 'selected': False, 'text': '<p>if you work on linux OS ,there is a command line <code>file --mimetype</code>: </p>\n\n<pre><code>String mimetype(file){\n\n   //1. run cmd\n   Object cmd=Runtime.getRuntime().exec("file --mime-type "+file);\n\n   //2 get output of cmd , then \n    //3. parse mimetype\n    if(output){return output.split(":")[1].trim(); }\n    return "";\n}\n</code></pre>\n\n<p>Then</p>\n\n<pre><code>mimetype("/home/nyapp.war") //  \'application/zip\'\n\nmimetype("/var/www/ggg/au.mp3") //  \'audio/mp3\'\n</code></pre>\n'}, {'answer_id': 36863737, 'author': 'Ahmad R. Nazemi', 'author_id': 979765, 'author_profile': 'https://Stackoverflow.com/users/979765', 'pm_score': 1, 'selected': False, 'text': '<p>in spring <strong>MultipartFile</strong> file;</p>\n\n<blockquote>\n  <p>org.springframework.web.multipart.MultipartFile</p>\n</blockquote>\n\n<p><code>file.getContentType();</code></p>\n'}, {'answer_id': 37461034, 'author': 'K. Siva Prasad Reddy', 'author_id': 755932, 'author_profile': 'https://Stackoverflow.com/users/755932', 'pm_score': 0, 'selected': False, 'text': '<p>After trying various other libraries I settled with mime-util.</p>\n\n<pre><code>&lt;groupId&gt;eu.medsea.mimeutil&lt;/groupId&gt;\n      &lt;artifactId&gt;mime-util&lt;/artifactId&gt;\n      &lt;version&gt;2.1.3&lt;/version&gt;\n&lt;/dependency&gt;\n\nFile file = new File("D:/test.tif");\nMimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");\nCollection&lt;?&gt; mimeTypes = MimeUtil.getMimeTypes(file);\nSystem.out.println(mimeTypes);\n</code></pre>\n'}, {'answer_id': 40765798, 'author': 'Vazgen Torosyan', 'author_id': 3541666, 'author_profile': 'https://Stackoverflow.com/users/3541666', 'pm_score': 0, 'selected': False, 'text': '<pre><code>public String getFileContentType(String fileName) {\n    String fileType = "Undetermined";\n    final File file = new File(fileName);\n    try\n    {\n        fileType = Files.probeContentType(file.toPath());\n    }\n    catch (IOException ioException)\n    {\n        System.out.println(\n                "ERROR: Unable to determine file type for " + fileName\n                        + " due to exception " + ioException);\n    }\n    return fileType;\n}\n</code></pre>\n'}, {'answer_id': 42229928, 'author': 'lifeisfoo', 'author_id': 3340702, 'author_profile': 'https://Stackoverflow.com/users/3340702', 'pm_score': 6, 'selected': False, 'text': '<p>With <a href="http://tika.apache.org" rel="noreferrer">Apache Tika</a> you need only <strong>three lines of code</strong>:</p>\n\n<pre><code>File file = new File("/path/to/file");\nTika tika = new Tika();\nSystem.out.println(tika.detect(file));\n</code></pre>\n\n<p>If you have a groovy console, just paste and run this code to play with it:</p>\n\n<pre><code>@Grab(\'org.apache.tika:tika-core:1.14\')\nimport org.apache.tika.Tika;\n\ndef tika = new Tika()\ndef file = new File("/path/to/file")\nprintln tika.detect(file)\n</code></pre>\n\n<p>Keep in mind that its APIs are rich, it can parse "anything". As of tika-core 1.14, you have:</p>\n\n<pre><code>String  detect(byte[] prefix)\nString  detect(byte[] prefix, String name)\nString  detect(File file)\nString  detect(InputStream stream)\nString  detect(InputStream stream, Metadata metadata)\nString  detect(InputStream stream, String name)\nString  detect(Path path)\nString  detect(String name)\nString  detect(URL url)\n</code></pre>\n\n<p>See <a href="http://tika.apache.org/1.14/api/" rel="noreferrer">the apidocs</a> for more information.</p>\n'}, {'answer_id': 42418284, 'author': 'madx', 'author_id': 3138238, 'author_profile': 'https://Stackoverflow.com/users/3138238', 'pm_score': 2, 'selected': False, 'text': '<p>This is the simplest way I found for doing this:</p>\n\n<pre><code>byte[] byteArray = ...\nInputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray));\nString mimeType = URLConnection.guessContentTypeFromStream(is);\n</code></pre>\n'}, {'answer_id': 46407125, 'author': 'nidalpres', 'author_id': 2268559, 'author_profile': 'https://Stackoverflow.com/users/2268559', 'pm_score': 3, 'selected': False, 'text': '<p>To chip in with my 5 cents:</p>\n\n<p><strong>TL,DR</strong></p>\n\n<p>I use <a href="https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html" rel="noreferrer">MimetypesFileTypeMap</a> and add any mime that is not there and I specifically need it, into mime.types file.</p>\n\n<p><em>And now, the long read:</em></p>\n\n<p>First of all, MIME types list is <em>huge</em>, see here: <a href="https://www.iana.org/assignments/media-types/media-types.xhtml" rel="noreferrer">https://www.iana.org/assignments/media-types/media-types.xhtml</a></p>\n\n<p>I like to use standard facilities provided by JDK first, and if that doesn\'t work, I\'ll go and look for something else.</p>\n\n<p><strong>Determine file type from file extension</strong></p>\n\n<p>Since 1.6, Java has MimetypesFileTypeMap, as pointed in one of the answers above, and it is the simplest way to determine mime type:</p>\n\n<pre><code>new MimetypesFileTypeMap().getContentType( fileName );\n</code></pre>\n\n<p>In its vanilla implementation this does not do much (i.e. it works for .html but it doesn\'t for .png). It is, however, super simple to add any content type you may need:</p>\n\n<ol>\n<li>Create file named \'mime.types\' in META-INF folder in your project</li>\n<li>Add a line for every mime type you need and default implementation doesn\'t provide (there are hundreds of mime types and list grows as time goes by).</li>\n</ol>\n\n<p>Example entries for png and js files would be:</p>\n\n<pre><code>image/png png PNG\napplication/javascript js\n</code></pre>\n\n<p>For mime.types file format, see more details here: <a href="https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html" rel="noreferrer">https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html</a></p>\n\n<p><strong>Determine file type from file content</strong></p>\n\n<p>Since 1.7, Java has <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/spi/FileTypeDetector.html" rel="noreferrer">java.nio.file.spi.FileTypeDetector</a>, which defines a standard API for determining a file type in <em>implementation specific way</em>.</p>\n\n<p>To fetch mime type for a file, you would simply use <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType(java.nio.file.Path)" rel="noreferrer">Files</a> and do this in your code:</p>\n\n<pre><code>Files.probeContentType(Paths.get("either file name or full path goes here"));\n</code></pre>\n\n<p>The API definition provides for facilities that support either for determining file mime type from file name or from file content (magic bytes). That is why <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/spi/FileTypeDetector.html#probeContentType(java.nio.file.Path)" rel="noreferrer">probeContentType()</a> method throws IOException, in case an implementation of this API uses Path provided to it to actually try to open the file associated with it.</p>\n\n<p>Again, vanilla <em>implementation</em> of this (the one that comes with JDK) leaves a lot to be desired.</p>\n\n<p>In some ideal world in a galaxy far, far away, all these libraries which try to solve this file-to-mime-type problem would simply implement <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/spi/FileTypeDetector.html" rel="noreferrer">java.nio.file.spi.FileTypeDetector</a>, you would drop in the preferred implementing library\'s jar file into your classpath and that would be it.</p>\n\n<p>In the real world, the one where you need TL,DR section, you should find the library with most stars next to it\'s name and use it. For this particular case, I don\'t need one (yet ;) ).</p>\n'}, {'answer_id': 48593136, 'author': 'Cassio Seffrin', 'author_id': 2449199, 'author_profile': 'https://Stackoverflow.com/users/2449199', 'pm_score': 2, 'selected': False, 'text': '<p>You can do it with just one line:  <strong>MimetypesFileTypeMap().getContentType(new File("filename.ext"))</strong>. Look the complete test code (Java 7):</p>\n\n<pre><code>import java.io.File;\nimport javax.activation.MimetypesFileTypeMap;\npublic class MimeTest {\n    public static void main(String a[]){\n         System.out.println(new MimetypesFileTypeMap().getContentType(\n           new File("/path/filename.txt")));\n    }\n}\n</code></pre>\n\n<p>This code produces the follow output: <strong>text/plain</strong></p>\n'}, {'answer_id': 56183154, 'author': 'ganesh vechalapu', 'author_id': 10384381, 'author_profile': 'https://Stackoverflow.com/users/10384381', 'pm_score': 0, 'selected': False, 'text': '<pre><code>File file = new File(PropertiesReader.FILE_PATH);\nMimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();\nString mimeType = fileTypeMap.getContentType(file);\nURLConnection uconnection = file.toURL().openConnection();\nmimeType = uconnection.getContentType();\n</code></pre>\n'}, {'answer_id': 57298455, 'author': 'sahmad', 'author_id': 3358877, 'author_profile': 'https://Stackoverflow.com/users/3358877', 'pm_score': -1, 'selected': False, 'text': '<p>I did it with following code. </p>\n\n<pre><code>import java.io.BufferedReader;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\n\npublic class MimeFileType {\n\n    public static void main(String args[]){\n\n        try{\n            URL url = new URL ("https://www.url.com.pdf");\n\n            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.setRequestMethod("GET");\n            connection.setDoOutput(true);\n            InputStream content = (InputStream)connection.getInputStream();\n            connection.getHeaderField("Content-Type");\n\n            System.out.println("Content-Type "+ connection.getHeaderField("Content-Type"));\n\n            BufferedReader in = new BufferedReader (new InputStreamReader(content));\n\n        }catch (Exception e){\n\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 58796361, 'author': 'Ramishka Dasanayaka', 'author_id': 1166830, 'author_profile': 'https://Stackoverflow.com/users/1166830', 'pm_score': 2, 'selected': False, 'text': '<p>If you are working with a Servlet and if the servlet context is available to you, you can use :</p>\n\n<pre><code>getServletContext().getMimeType( fileName );\n</code></pre>\n'}, {'answer_id': 61716681, 'author': 'Pratik Gaurav', 'author_id': 5845739, 'author_profile': 'https://Stackoverflow.com/users/5845739', 'pm_score': 2, 'selected': False, 'text': '<p>Apache Tika.</p>\n\n<pre><code>&lt;!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers --&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.apache.tika&lt;/groupId&gt;\n    &lt;artifactId&gt;tika-parsers&lt;/artifactId&gt;\n    &lt;version&gt;1.24&lt;/version&gt;\n&lt;/dependency&gt;\n\n</code></pre>\n\n<p>and Two line of code.</p>\n\n<pre><code>Tika tika=new Tika();\ntika.detect(inputStream);\n</code></pre>\n\n<p>Screenshot below</p>\n\n<p><a href="https://i.stack.imgur.com/zGTrB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zGTrB.png" alt="enter image description here"></a></p>\n'}, {'answer_id': 64671146, 'author': 'Samuel Prevost', 'author_id': 5989906, 'author_profile': 'https://Stackoverflow.com/users/5989906', 'pm_score': 2, 'selected': False, 'text': '<p>I couldn\'t find anything to check for <code>video/mp4</code> MIME type so I made my own solution.\nI happened to observe that Wikipedia was wrong and that the <code>00 00 00 18 66 74 79 70 69 73 6F 6D</code> file signature is not correct. the fourth byte (<code>18</code>) and all <code>70</code> (excluded) after changes quite a lot amongst otherwise valid <code>mp4</code> files.</p>\n<p>This code is essentially a copy/paste of <code>URLConnection.guessContentTypeFromStream</code> code but tailored to <code>video/mp4</code>.</p>\n<pre class="lang-java prettyprint-override"><code>BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content));\nString mimeType = URLConnection.guessContentTypeFromStream(bis);\n\n// Goes full barbaric and processes the bytes manually\nif (mimeType == null){\n    // These ints converted in hex ar:\n    // 00 00 00 18 66 74 79 70 69 73 6F 6D\n    // which are the file signature (magic bytes) for .mp4 files\n    // from https://www.wikiwand.com/en/List_of_file_signatures\n    // just ctrl+f &quot;mp4&quot;\n    int[] mp4_sig = {0, 0, 0, 24, 102, 116, 121, 112};\n\n    bis.reset();\n    bis.mark(16);\n    int[] firstBytes = new int[8];\n    for (int i = 0; i &lt; 8; i++) {\n        firstBytes[i] = bis.read();\n    }\n    // This byte doesn\'t matter for the file signature and changes\n    mp4_sig[3] = content[3];\n\n    bis.reset();\n    if (Arrays.equals(firstBytes, mp4_sig)){\n        mimeType = &quot;video/mp4&quot;;\n    }\n}\n</code></pre>\n<p>Tested successfully against 10 different <code>.mp4</code> files.</p>\n<p>EDIT: <a href="http://mirrors.standaloneinstaller.com/video-sample/" rel="nofollow noreferrer">Here is a useful link (if it is still online) where you can find samples of many types</a>. I don\'t own those videos, don\'t know who does either, but they\'re useful for testing the above code.</p>\n'}, {'answer_id': 65696342, 'author': 'Lorenzo', 'author_id': 3225638, 'author_profile': 'https://Stackoverflow.com/users/3225638', 'pm_score': 0, 'selected': False, 'text': '<p>Check the magic bytes of the stream or file:</p>\n<p><a href="https://stackoverflow.com/a/65667558/3225638">https://stackoverflow.com/a/65667558/3225638</a></p>\n<p>It uses pure Java, but requires you to define an <code>enum</code> of the types you want to detect.</p>\n'}, {'answer_id': 66944463, 'author': 'Dave Jarvis', 'author_id': 59087, 'author_profile': 'https://Stackoverflow.com/users/59087', 'pm_score': 1, 'selected': False, 'text': '<p>A solution to detecting a file\'s <a href="https://www.iana.org/assignments/media-types/media-types.xhtml" rel="nofollow noreferrer">Media Type</a><sup>1</sup> has the following parts:</p>\n<ul>\n<li>A list of file signatures (see <a href="https://www.garykessler.net/library/file_sigs.html" rel="nofollow noreferrer">Kessler\'s list</a>, <a href="https://en.wikipedia.org/wiki/List_of_file_signatures" rel="nofollow noreferrer">Wikipedia\'s list</a>, and <a href="https://github.com/veniware/Space-Maker/blob/master/FileSignatures.cs" rel="nofollow noreferrer">Space Maker\'s list</a>)</li>\n<li>A list of Media Types</li>\n<li>A map of Media Types to file name extensions</li>\n<li>Comparing file signatures against <code>File</code>, <code>Path</code>, or <code>InputStream</code> data sources</li>\n</ul>\n<p>Please remember to give credit if you copy the code.</p>\n<h1>StreamMediaType.java</h1>\n<p>In the following code <code>-1</code> means skip comparing the byte at that index; a <code>-2</code> denotes end of file type signature. This detects binary formats, primarily images, and a few plain text format variations (HTML, SVG, XML). The code uses up to the first 11 &quot;magic&quot; bytes from the data source\'s header. Optimizations and improvements that shorten the logic are welcome.</p>\n<pre class="lang-java prettyprint-override"><code>import java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Path;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport static com.keenwrite.io.MediaType.*;\nimport static java.lang.System.arraycopy;\n\npublic class StreamMediaType {\n  private static final int FORMAT_LENGTH = 11;\n  private static final int END_OF_DATA = -2;\n\n  private static final Map&lt;int[], MediaType&gt; FORMAT = new LinkedHashMap&lt;&gt;();\n\n  static {\n    //@formatter:off\n    FORMAT.put( ints( 0x3C, 0x73, 0x76, 0x67, 0x20 ), IMAGE_SVG_XML );\n    FORMAT.put( ints( 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ), IMAGE_PNG );\n    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xE0 ), IMAGE_JPEG );\n    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xEE ), IMAGE_JPEG );\n    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xE1, -1, -1, 0x45, 0x78, 0x69, 0x66, 0x00 ), IMAGE_JPEG );\n    FORMAT.put( ints( 0x49, 0x49, 0x2A, 0x00 ), IMAGE_TIFF );\n    FORMAT.put( ints( 0x4D, 0x4D, 0x00, 0x2A ), IMAGE_TIFF );\n    FORMAT.put( ints( 0x47, 0x49, 0x46, 0x38 ), IMAGE_GIF );\n    FORMAT.put( ints( 0x8A, 0x4D, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ), VIDEO_MNG );\n    FORMAT.put( ints( 0x25, 0x50, 0x44, 0x46, 0x2D, 0x31, 0x2E ), APP_PDF );\n    FORMAT.put( ints( 0x38, 0x42, 0x50, 0x53, 0x00, 0x01 ), IMAGE_PHOTOSHOP );\n    FORMAT.put( ints( 0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x2D ), APP_EPS );\n    FORMAT.put( ints( 0x25, 0x21, 0x50, 0x53 ), APP_PS );\n    FORMAT.put( ints( 0xFF, 0xFB, 0x30 ), AUDIO_MP3 );\n    FORMAT.put( ints( 0x49, 0x44, 0x33 ), AUDIO_MP3 );\n    FORMAT.put( ints( 0x3C, 0x21 ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x68, 0x74, 0x6D, 0x6C ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x68, 0x65, 0x61, 0x64 ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x62, 0x6F, 0x64, 0x79 ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x48, 0x54, 0x4D, 0x4C ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x48, 0x45, 0x41, 0x44 ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x42, 0x4F, 0x44, 0x59 ), TEXT_HTML );\n    FORMAT.put( ints( 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20 ), TEXT_XML );\n    FORMAT.put( ints( 0xFE, 0xFF, 0x00, 0x3C, 0x00, 0x3f, 0x00, 0x78 ), TEXT_XML );\n    FORMAT.put( ints( 0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00 ), TEXT_XML );\n    FORMAT.put( ints( 0x42, 0x4D ), IMAGE_BMP );\n    FORMAT.put( ints( 0x23, 0x64, 0x65, 0x66 ), IMAGE_X_BITMAP );\n    FORMAT.put( ints( 0x21, 0x20, 0x58, 0x50, 0x4D, 0x32 ), IMAGE_X_PIXMAP );\n    FORMAT.put( ints( 0x2E, 0x73, 0x6E, 0x64 ), AUDIO_BASIC );\n    FORMAT.put( ints( 0x64, 0x6E, 0x73, 0x2E ), AUDIO_BASIC );\n    FORMAT.put( ints( 0x52, 0x49, 0x46, 0x46 ), AUDIO_WAV );\n    FORMAT.put( ints( 0x50, 0x4B ), APP_ZIP );\n    FORMAT.put( ints( 0x41, 0x43, -1, -1, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00 ), APP_ACAD );\n    FORMAT.put( ints( 0xCA, 0xFE, 0xBA, 0xBE ), APP_JAVA );\n    FORMAT.put( ints( 0xAC, 0xED ), APP_JAVA_OBJECT );\n    //@formatter:on\n  }\n\n  private StreamMediaType() {\n  }\n\n  public static MediaType getMediaType( final Path path ) throws IOException {\n    return getMediaType( path.toFile() );\n  }\n\n  public static MediaType getMediaType( final java.io.File file )\n    throws IOException {\n    try( final var fis = new FileInputStream( file ) ) {\n      return getMediaType( fis );\n    }\n  }\n\n  public static MediaType getMediaType( final InputStream is )\n    throws IOException {\n    final var input = new byte[ FORMAT_LENGTH ];\n    final var count = is.read( input, 0, FORMAT_LENGTH );\n\n    if( count &gt; 1 ) {\n      final var available = new byte[ count ];\n      arraycopy( input, 0, available, 0, count );\n      return getMediaType( available );\n    }\n\n    return UNDEFINED;\n  }\n\n  public static MediaType getMediaType( final byte[] data ) {\n    assert data != null;\n\n    final var source = new int[]{\n      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\n\n    for( int i = 0; i &lt; data.length; i++ ) {\n      source[ i ] = data[ i ] &amp; 0xFF;\n    }\n\n    for( final var key : FORMAT.keySet() ) {\n      int i = -1;\n      boolean matches = true;\n\n      while( ++i &lt; FORMAT_LENGTH &amp;&amp; key[ i ] != END_OF_DATA &amp;&amp; matches ) {\n        matches = key[ i ] == source[ i ] || key[ i ] == -1;\n      }\n\n      if( matches ) {\n        return FORMAT.get( key );\n      }\n    }\n\n    return UNDEFINED;\n  }\n\n  private static int[] ints( final int... data ) {\n    final var magic = new int[ FORMAT_LENGTH ];\n    int i = -1;\n    while( ++i &lt; data.length ) {\n      magic[ i ] = data[ i ];\n    }\n\n    while( i &lt; FORMAT_LENGTH ) {\n      magic[ i++ ] = END_OF_DATA;\n    }\n\n    return magic;\n  }\n}\n</code></pre>\n<h1>MediaType.java</h1>\n<p>Define the file formats according to the <a href="https://www.iana.org/assignments/media-types/media-types.xhtml" rel="nofollow noreferrer">IANA Media Type</a> list. Notice that the file name extensions are mapped in <code>MediaTypeExtension</code>. There\'s a dependency on Apache\'s FilenameUtils class for its <code>getExtension</code> function.</p>\n<pre class="lang-java prettyprint-override"><code>import java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Path;\n\nimport static MediaType.TypeName.*;\nimport static MediaTypeExtension.getMediaType;\nimport static org.apache.commons.io.FilenameUtils.getExtension;\n\npublic enum MediaType {\n  APP_ACAD( APPLICATION, &quot;acad&quot; ),\n  APP_JAVA_OBJECT( APPLICATION, &quot;x-java-serialized-object&quot; ),\n  APP_JAVA( APPLICATION, &quot;java&quot; ),\n  APP_PS( APPLICATION, &quot;postscript&quot; ),\n  APP_EPS( APPLICATION, &quot;eps&quot; ),\n  APP_PDF( APPLICATION, &quot;pdf&quot; ),\n  APP_ZIP( APPLICATION, &quot;zip&quot; ),\n  FONT_OTF( &quot;otf&quot; ),\n  FONT_TTF( &quot;ttf&quot; ),\n  IMAGE_APNG( &quot;apng&quot; ),\n  IMAGE_ACES( &quot;aces&quot; ),\n  IMAGE_AVCI( &quot;avci&quot; ),\n  IMAGE_AVCS( &quot;avcs&quot; ),\n  IMAGE_BMP( &quot;bmp&quot; ),\n  IMAGE_CGM( &quot;cgm&quot; ),\n  IMAGE_DICOM_RLE( &quot;dicom_rle&quot; ),\n  IMAGE_EMF( &quot;emf&quot; ),\n  IMAGE_EXAMPLE( &quot;example&quot; ),\n  IMAGE_FITS( &quot;fits&quot; ),\n  IMAGE_G3FAX( &quot;g3fax&quot; ),\n  IMAGE_GIF( &quot;gif&quot; ),\n  IMAGE_HEIC( &quot;heic&quot; ),\n  IMAGE_HEIF( &quot;heif&quot; ),\n  IMAGE_HEJ2K( &quot;hej2k&quot; ),\n  IMAGE_HSJ2( &quot;hsj2&quot; ),\n  IMAGE_X_ICON( &quot;x-icon&quot; ),\n  IMAGE_JLS( &quot;jls&quot; ),\n  IMAGE_JP2( &quot;jp2&quot; ),\n  IMAGE_JPEG( &quot;jpeg&quot; ),\n  IMAGE_JPH( &quot;jph&quot; ),\n  IMAGE_JPHC( &quot;jphc&quot; ),\n  IMAGE_JPM( &quot;jpm&quot; ),\n  IMAGE_JPX( &quot;jpx&quot; ),\n  IMAGE_JXR( &quot;jxr&quot; ),\n  IMAGE_JXRA( &quot;jxrA&quot; ),\n  IMAGE_JXRS( &quot;jxrS&quot; ),\n  IMAGE_JXS( &quot;jxs&quot; ),\n  IMAGE_JXSC( &quot;jxsc&quot; ),\n  IMAGE_JXSI( &quot;jxsi&quot; ),\n  IMAGE_JXSS( &quot;jxss&quot; ),\n  IMAGE_KTX( &quot;ktx&quot; ),\n  IMAGE_KTX2( &quot;ktx2&quot; ),\n  IMAGE_NAPLPS( &quot;naplps&quot; ),\n  IMAGE_PNG( &quot;png&quot; ),\n  IMAGE_PHOTOSHOP( &quot;photoshop&quot; ),\n  IMAGE_SVG_XML( &quot;svg+xml&quot; ),\n  IMAGE_T38( &quot;t38&quot; ),\n  IMAGE_TIFF( &quot;tiff&quot; ),\n  IMAGE_WEBP( &quot;webp&quot; ),\n  IMAGE_WMF( &quot;wmf&quot; ),\n  IMAGE_X_BITMAP( &quot;x-xbitmap&quot; ),\n  IMAGE_X_PIXMAP( &quot;x-xpixmap&quot; ),\n  AUDIO_BASIC( AUDIO, &quot;basic&quot; ),\n  AUDIO_MP3( AUDIO, &quot;mp3&quot; ),\n  AUDIO_WAV( AUDIO, &quot;x-wav&quot; ),\n  VIDEO_MNG( VIDEO, &quot;x-mng&quot; ),\n  TEXT_HTML( TEXT, &quot;html&quot; ),\n  TEXT_MARKDOWN( TEXT, &quot;markdown&quot; ),\n  TEXT_PLAIN( TEXT, &quot;plain&quot; ),\n  TEXT_XHTML( TEXT, &quot;xhtml+xml&quot; ),\n  TEXT_XML( TEXT, &quot;xml&quot; ),\n  TEXT_YAML( TEXT, &quot;yaml&quot; ),\n\n  /*\n   * When all other lights go out.\n   */\n  UNDEFINED( TypeName.UNDEFINED, &quot;undefined&quot; );\n\n  public enum TypeName {\n    APPLICATION,\n    AUDIO,\n    IMAGE,\n    TEXT,\n    UNDEFINED,\n    VIDEO\n  }\n\n  private final String mMediaType;\n  private final TypeName mTypeName;\n  private final String mSubtype;\n\n  MediaType( final String subtype ) {\n    this( IMAGE, subtype );\n  }\n\n  MediaType( final TypeName typeName, final String subtype ) {\n    mTypeName = typeName;\n    mSubtype = subtype;\n    mMediaType = typeName.toString().toLowerCase() + \'/\' + subtype;\n  }\n\n  public static MediaType valueFrom( final File file ) {\n    assert file != null;\n    return fromFilename( file.getName() );\n  }\n\n  public static MediaType fromFilename( final String filename ) {\n    assert filename != null;\n    return getMediaType( getExtension( filename ) );\n  }\n\n  public static MediaType valueFrom( final Path path ) {\n    assert path != null;\n    return valueFrom( path.toFile() );\n  }\n\n  public static MediaType valueFrom( String contentType ) {\n    if( contentType == null || contentType.isBlank() ) {\n      return UNDEFINED;\n    }\n\n    var i = contentType.indexOf( \';\' );\n    contentType = contentType.substring(\n      0, i == -1 ? contentType.length() : i );\n\n    i = contentType.indexOf( \'/\' );\n    i = i == -1 ? contentType.length() : i;\n    final var type = contentType.substring( 0, i );\n    final var subtype = contentType.substring( i + 1 );\n\n    return valueFrom( type, subtype );\n  }\n\n  public static MediaType valueFrom(\n    final String type, final String subtype ) {\n    assert type != null;\n    assert subtype != null;\n\n    for( final var mediaType : values() ) {\n      if( mediaType.equals( type, subtype ) ) {\n        return mediaType;\n      }\n    }\n\n    return UNDEFINED;\n  }\n\n  public boolean equals( final String type, final String subtype ) {\n    assert type != null;\n    assert subtype != null;\n\n    return mTypeName.name().equalsIgnoreCase( type ) &amp;&amp;\n      mSubtype.equalsIgnoreCase( subtype );\n  }\n\n  public boolean isType( final TypeName typeName ) {\n    return mTypeName == typeName;\n  }\n\n  public String getSubtype() {\n    return mSubtype;\n  }\n   \n  @Override\n  public String toString() {\n    return mMediaType;\n  }\n}\n</code></pre>\n<h1>MediaTypeExtension.java</h1>\n<p>Last piece of the puzzle is a map of <code>MediaType</code>s to their known and common/popular file name extensions. This allows bidirectional lookup based on file name extensions.</p>\n<pre class="lang-java prettyprint-override"><code>import static MediaType.*;\nimport static java.util.List.of;\n\npublic enum MediaTypeExtension {\n  MEDIA_APP_ACAD( APP_ACAD, of( &quot;dwg&quot; ) ),\n  MEDIA_APP_PDF( APP_PDF ),\n  MEDIA_APP_PS( APP_PS, of( &quot;ps&quot; ) ),\n  MEDIA_APP_EPS( APP_EPS ),\n  MEDIA_APP_ZIP( APP_ZIP ),\n\n  MEDIA_AUDIO_MP3( AUDIO_MP3 ),\n  MEDIA_AUDIO_BASIC( AUDIO_BASIC, of( &quot;au&quot; ) ),\n  MEDIA_AUDIO_WAV( AUDIO_WAV, of( &quot;wav&quot; ) ),\n\n  MEDIA_FONT_OTF( FONT_OTF ),\n  MEDIA_FONT_TTF( FONT_TTF ),\n\n  MEDIA_IMAGE_APNG( IMAGE_APNG ),\n  MEDIA_IMAGE_BMP( IMAGE_BMP ),\n  MEDIA_IMAGE_GIF( IMAGE_GIF ),\n  MEDIA_IMAGE_JPEG( IMAGE_JPEG,\n                    of( &quot;jpg&quot;, &quot;jpe&quot;, &quot;jpeg&quot;, &quot;jfif&quot;, &quot;pjpeg&quot;, &quot;pjp&quot; ) ),\n  MEDIA_IMAGE_PNG( IMAGE_PNG ),\n  MEDIA_IMAGE_PSD( IMAGE_PHOTOSHOP, of( &quot;psd&quot; ) ),\n  MEDIA_IMAGE_SVG( IMAGE_SVG_XML, of( &quot;svg&quot; ) ),\n  MEDIA_IMAGE_TIFF( IMAGE_TIFF, of( &quot;tiff&quot;, &quot;tif&quot; ) ),\n  MEDIA_IMAGE_WEBP( IMAGE_WEBP ),\n  MEDIA_IMAGE_X_BITMAP( IMAGE_X_BITMAP, of( &quot;xbm&quot; ) ),\n  MEDIA_IMAGE_X_PIXMAP( IMAGE_X_PIXMAP, of( &quot;xpm&quot; ) ),\n\n  MEDIA_VIDEO_MNG( VIDEO_MNG, of( &quot;mng&quot; ) ),\n\n  MEDIA_TEXT_MARKDOWN( TEXT_MARKDOWN, of(\n    &quot;md&quot;, &quot;markdown&quot;, &quot;mdown&quot;, &quot;mdtxt&quot;, &quot;mdtext&quot;, &quot;mdwn&quot;, &quot;mkd&quot;, &quot;mkdown&quot;,\n    &quot;mkdn&quot; ) ),\n  MEDIA_TEXT_PLAIN( TEXT_PLAIN, of( &quot;txt&quot;, &quot;asc&quot;, &quot;ascii&quot;, &quot;text&quot;, &quot;utxt&quot; ) ),\n  MEDIA_TEXT_R_MARKDOWN( TEXT_R_MARKDOWN, of( &quot;Rmd&quot; ) ),\n  MEDIA_TEXT_R_XML( TEXT_R_XML, of( &quot;Rxml&quot; ) ),\n  MEDIA_TEXT_XHTML( TEXT_XHTML, of( &quot;xhtml&quot; ) ),\n  MEDIA_TEXT_XML( TEXT_XML ),\n  MEDIA_TEXT_YAML( TEXT_YAML, of( &quot;yaml&quot;, &quot;yml&quot; ) ),\n\n  MEDIA_UNDEFINED( UNDEFINED, of( &quot;undefined&quot; ) );\n\n  private final MediaType mMediaType;\n  private final List&lt;String&gt; mExtensions;\n\n  MediaTypeExtension( final MediaType mediaType ) {\n    this( mediaType, of( mediaType.getSubtype() ) );\n  }\n\n  MediaTypeExtension(\n    final MediaType mediaType, final List&lt;String&gt; extensions ) {\n    assert mediaType != null;\n    assert extensions != null;\n    assert !extensions.isEmpty();\n\n    mMediaType = mediaType;\n    mExtensions = extensions;\n  }\n\n  public String getExtension() {\n    return mExtensions.get( 0 );\n  }\n\n  public static MediaTypeExtension valueFrom( final MediaType mediaType ) {\n    for( final var type : values() ) {\n      if( type.isMediaType( mediaType ) ) {\n        return type;\n      }\n    }\n\n    return MEDIA_UNDEFINED;\n  }\n\n  boolean isMediaType( final MediaType mediaType ) {\n    return mMediaType == mediaType;\n  }\n\n  static MediaType getMediaType( final String extension ) {\n    final var sanitized = sanitize( extension );\n\n    for( final var mediaType : MediaTypeExtension.values() ) {\n      if( mediaType.isType( sanitized ) ) {\n        return mediaType.getMediaType();\n      }\n    }\n\n    return UNDEFINED;\n  }\n\n  private boolean isType( final String sanitized ) {\n    for( final var extension : mExtensions ) {\n      if( extension.equalsIgnoreCase( sanitized ) ) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  private static String sanitize( final String extension ) {\n    return extension == null ? &quot;&quot; : extension.toLowerCase();\n  }\n\n  private MediaType getMediaType() {\n    return mMediaType;\n  }\n}\n</code></pre>\n<hr />\n<p>Usages:</p>\n<pre class="lang-java prettyprint-override"><code>// EXAMPLE -- Detect media type\n//\nfinal File image = new File( &quot;filename.jpg&quot; );\nfinal MediaType mt = StreamMediaType.getMediaType( image );\n\n// Tricky! The JPG could be a PNG in disguise.\nif( mt.isType( MediaType.TypeName.IMAGE ) ) {\n\n  if( mt == MediaType.IMAGE_PNG ) {\n    // Nice try! Sneaky sneak.\n  }\n}\n\n// EXAMPLE -- Get typical media type file name extension\n//\nfinal String ext = MediaTypeExtension.valueFrom( MediaType.IMAGE_SVG_XML ).getExtension();\n\n// EXAMPLE -- Get media type from HTTP request\n//\nfinal var url = new URL( &quot;https://localhost/path/file.ext&quot; );\nfinal var conn = (HttpURLConnection) url.openConnection();\nfinal var contentType = conn.getContentType();\nMediaType mediaType = valueFrom( contentType );\n\n// Fall back to stream detection probe\nif( mediaType == UNDEFINED ) {\n  mediaType = StreamMediaType.getMediaType( conn.getInputStream() );\n}\n\nconn.disconnect();\n</code></pre>\n<p>You get the idea.</p>\n<hr />\n<p>Short library review:</p>\n<ul>\n<li><a href="https://tika.apache.org/" rel="nofollow noreferrer">Apache Tika</a> -- 600kb bloat, needs multiple lines to configure, and multiple JAR files.</li>\n<li><a href="https://github.com/arimus/jmimemagic/" rel="nofollow noreferrer">jMimeMagic</a> -- Unfinished, needs multiple lines to configure.</li>\n<li><a href="http://mime-util.sourceforge.net/" rel="nofollow noreferrer">MimeUtil2</a> -- Fairly large, didn\'t work out-of-the-box.</li>\n<li><a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/spi/FileTypeDetector.html" rel="nofollow noreferrer">FileTypeDetector</a> -- Bundled with JDK, buggier than a mountain pine beetle infested forest.</li>\n<li><a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/spi/FileTypeDetector.html" rel="nofollow noreferrer">Files.probeContentType</a> -- Detection is platform-specific and considered unreliable (<a href="https://stackoverflow.com/a/65966588/59087">source</a>).</li>\n<li><a href="https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html" rel="nofollow noreferrer">MimetypesFileTypeMap</a> -- Bundled with activation.jar, uses file name extension.</li>\n</ul>\n<hr />\n<p>Sample audio, video, and image files for testing:</p>\n<ul>\n<li><a href="http://mirrors.standaloneinstaller.com/video-sample/" rel="nofollow noreferrer">http://mirrors.standaloneinstaller.com/video-sample/</a></li>\n<li><a href="https://www.w3.org/People/mimasa/test/imgformat/" rel="nofollow noreferrer">https://www.w3.org/People/mimasa/test/imgformat/</a></li>\n</ul>\n<hr />\n<p><sup>1</sup> &quot;MIME type&quot; is a deprecated term.</p>\n'}, {'answer_id': 67586306, 'author': 'user1050755', 'author_id': 1050755, 'author_profile': 'https://Stackoverflow.com/users/1050755', 'pm_score': 0, 'selected': False, 'text': '<p>If you want a reliable (ie. consistent) way of mapping file extensions to mime-types, here is what I use:</p>\n<p><a href="https://github.com/jjYBdx4IL/misc/blob/master/text-utils/src/main/java/com/github/jjYBdx4IL/utils/text/MimeType.java" rel="nofollow noreferrer">https://github.com/jjYBdx4IL/misc/blob/master/text-utils/src/main/java/com/github/jjYBdx4IL/utils/text/MimeType.java</a></p>\n<p>It includes a bundled mime types database and basically inverts the logic of javax.activation\'s MimetypesFileTypeMap class by using the database to initialize the &quot;programmatic&quot; entries. That way the library-defined types always have precedence over what may be defined in unbundled resources.</p>\n'}, {'answer_id': 69737453, 'author': 'MIsmail', 'author_id': 4836726, 'author_profile': 'https://Stackoverflow.com/users/4836726', 'pm_score': 2, 'selected': False, 'text': '<p>Actually, <a href="https://tika.apache.org/2.1.0/detection.html" rel="nofollow noreferrer">Apache Tika detector</a> <code>Tika.detect(File)</code> is the best option and more accurate than <code>Files.probeContentType(path)</code>.</p>\n<p>check this <a href="https://dzone.com/articles/determining-file-types-java" rel="nofollow noreferrer">great quick reference</a> which contains examples and code samples.</p>\n'}]
['https://Stackoverflow.com/questions/51438', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1900/']