<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java獲取文件類(lèi)型的5種方法

          共 4137字,需瀏覽 9分鐘

           ·

          2021-02-05 08:27

          前言

          工作中經(jīng)常會(huì)用到,判斷一個(gè)文件的文件類(lèi)型,這里總結(jié)一把,一般判斷文件類(lèi)型的原理有2種方式:

          1. 根據(jù)文件擴(kuò)展名判斷

            • 優(yōu)點(diǎn):速度快,代碼簡(jiǎn)單
            • 缺點(diǎn):無(wú)法判斷出真實(shí)的文件類(lèi)型,例如一些偽造的文件或者沒(méi)有后綴名稱(chēng)的文件
          2. 根據(jù)文件流中前幾個(gè)字符判斷

            • 優(yōu)點(diǎn):可以判斷出真實(shí)的文件類(lèi)型
            • 缺點(diǎn):速度慢,代碼復(fù)雜

          下面我會(huì)針對(duì)每個(gè)方法,去測(cè)試驗(yàn)證,測(cè)試文件如下:

          1. test.png: 創(chuàng)建一個(gè)正常的png文件,其擴(kuò)展名為test.png

          2. test.doc: 復(fù)制一份上面的test.png文件,修改其文件名稱(chēng)為test.doc

          1. 使用Files.probeContentType

          Java1.7開(kāi)始,提供了用于解決MIME類(lèi)型的方法 Files.probeContentType:

          ????public?static?void?test()?throws?IOException?{
          ????????Path?path?=?new?File("d:/test.png").toPath();
          ????????String?mimeType?=?Files.probeContentType(path);
          ????????System.out.println(mimeType);
          ????}

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docapplication/msword?

          此方法利用已安裝的FileTypeDetector實(shí)現(xiàn)來(lái)探查MIME類(lèi)型。它調(diào)用每個(gè)實(shí)現(xiàn)的 probeContentType來(lái)解析類(lèi)型。

          但是,其默認(rèn)實(shí)現(xiàn)是特定于操作系統(tǒng)的,并且可能會(huì)失敗,具體取決于我們使用的操作系統(tǒng)。

          結(jié)論:根據(jù)文件擴(kuò)展名判斷。

          2. 使用URLConnection

          URLConnection提供了幾種用于檢測(cè)文件的MIME類(lèi)型的API。

          2.1 使用getContentType

          public?void?test(){
          ????File?file?=?new?File("d:/test.png");
          ????URLConnection?connection?=?file.toURL().openConnection();
          ????String?mimeType?=?connection.getContentType();
          }

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docimage/png??

          結(jié)論:根據(jù)文件流中前幾個(gè)字符判斷。能夠判斷真實(shí)的文件類(lèi)型,但是,這種方法的主要缺點(diǎn)是速度非常慢

          2.2 使用guessContentTypeFromName

          public?void?test(){
          ????File?file?=?new?File("d:/test.png");
          ????String?mimeType?=?URLConnection.guessContentTypeFromName(file.getName());
          }

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docnull? 具體參考下面的2.4

          該方法利用內(nèi)部的FileNameMap來(lái)判斷MIME類(lèi)型。

          結(jié)論:根據(jù)文件擴(kuò)展名判斷。

          2.3 使用guessContentTypeFromStream

          ????public?static?void?test()?throws?Exception?{
          ????????FileInputStream?inputFile?=?new?FileInputStream("d:/test.doc");
          ????????String?mimeType?=?URLConnection.guessContentTypeFromStream(new?BufferedInputStream(inputFile));
          ????????System.out.println(mimeType);
          ????}

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docimage/png??

          結(jié)論:根據(jù)文件流中前幾個(gè)字符判斷

          2.4 使用getFileNameMap

          使用URLConnection獲得MIME類(lèi)型的更快方法是使用getFileNameMap()方法:

          public?void?test(){
          ????File?file?=?new?File("d:/test.png");
          ????FileNameMap?fileNameMap?=?URLConnection.getFileNameMap();
          ????String?mimeType?=?fileNameMap.getContentTypeFor(file.getName());
          }

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docnull?

          該方法返回URLConnection的所有實(shí)例使用的MIME類(lèi)型表。然后,該表用于解析輸入文件類(lèi)型。

          當(dāng)涉及URLConnection時(shí),MIME類(lèi)型的內(nèi)置表非常有限。

          默認(rèn)情況下,該類(lèi)使用content-types.properties文件,其所在目錄為JRE_HOME/lib。但是,我們可以通過(guò)使用content.types.user.table屬性指定用戶(hù)特定的表來(lái)擴(kuò)展它 :

          System.setProperty("content.types.user.table","");

          結(jié)論:根據(jù)文件擴(kuò)展名判斷。

          3. 使用MimeTypesFileTypeMap

          該類(lèi)是Java 6附帶的,因此在使用JDK 1.6時(shí)非常方便。

          public?void?test()?{
          ????File?file?=?new?File("product.png");
          ????MimetypesFileTypeMap?fileTypeMap?=?new?MimetypesFileTypeMap();
          ????String?mimeType?=?fileTypeMap.getContentType(file.getName());
          }

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docapplication/octet-stream?

          在這里,我們可以將文件名或File實(shí)例本身作為參數(shù)傳遞給函數(shù)。但是,以File實(shí)例為參數(shù)的函數(shù)在內(nèi)部調(diào)用重載方法,該方法接受文件名作為參數(shù)。

          在內(nèi)部,此方法查找名為mime.types的文件以進(jìn)行類(lèi)型解析。請(qǐng)務(wù)必注意,該方法以特定順序搜索文件:

          1. 以編程方式將條目添加到MimetypesFileTypeMap實(shí)例
          2. 用戶(hù)主目錄中的mime.types
          3. /lib/mime.types
          4. 名為META-INF / mime.types的資源
          5. 名為META-INF / mimetypes.default的資源(通常僅在activation.jar文件中找到)

          但是,如果找不到文件,它將返回application/octet-stream作為響應(yīng)。

          結(jié)論:根據(jù)文件擴(kuò)展名判斷。

          4. 使用jmimemagic

          jMimeMagic是一個(gè)受限制許可的庫(kù),我們可以使用它來(lái)獲取文件的MIME類(lèi)型。

          配置Maven依賴(lài):


          ????net.sf.jmimemagic
          ????jmimemagic
          ????0.1.5

          接下來(lái),我們將探討如何使用該庫(kù):

          public?void?test()?{
          ????????File?file?=?new?File("d:/test.doc");
          ????????MagicMatch?match?=?Magic.getMagicMatch(file,?false);
          ????????System.out.println(match.getMimeType());
          }

          該庫(kù)可以處理數(shù)據(jù)流,因此不需要文件存在于文件系統(tǒng)中。

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docimage/png??

          結(jié)論:根據(jù)文件流中前幾個(gè)字符判斷

          5. 使用Apache Tika

          Apache Tika是一個(gè)工具集,可檢測(cè)并從各種文件中提取元數(shù)據(jù)和文本。它具有豐富而強(qiáng)大的API,并帶有[tika-core],我們可以利用它來(lái)檢測(cè)文件的MIME類(lèi)型。

          配置Maven依賴(lài):


          ????org.apache.tika
          ????tika-core
          ????1.18

          接下來(lái),我們將使用detect()方法來(lái)解析類(lèi)型:

          public?void?whenUsingTika_thenSuccess()?{
          ????File?file?=?new?File("d:/test.doc");
          ????Tika?tika?=?new?Tika();
          ????String?mimeType?=?tika.detect(file);
          }

          結(jié)果

          文件結(jié)果結(jié)論
          test.pngimage/png??
          test.docimage/png??

          結(jié)論:根據(jù)文件流中前幾個(gè)字符判斷

          總結(jié)

          根據(jù)判斷原理總結(jié)分類(lèi)如下:

          判斷原理方式
          根據(jù)文件擴(kuò)展名1.Files.probeContentType
          2.URLConnection.guessContentTypeFromName
          3.URLConnection.getFileNameMap
          4.MimetypesFileTypeMap
          根據(jù)文件流中前幾個(gè)字符1.URLConnection.getContentType
          2.URLConnection.guessContentTypeFromStream
          3.jmimemagic
          4.tika

          具體如何選擇,依據(jù)需求而定

          參考:https://www.baeldung.com/java-file-mime-type


          往期推薦

          最常見(jiàn)的10種Java異常問(wèn)題!


          SpringBoot接口冪等性實(shí)現(xiàn)的4種方案!


          對(duì)象復(fù)制的7種方法,還是Spring的最好用!


          關(guān)注我,每天陪你進(jìn)步一點(diǎn)點(diǎn)!

          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  做爱的免费网站 | 福利在线91 | 日韩特黄一级片 | 欧美老妇乱伦视频 | 国产变态视频a片一二三 |