Java如何判断一个上传文件的内容类型
關(guān)于如何判斷一個(gè)文件的類型,在如何判斷一個(gè)文件的類型_jimmyleeee的博客-CSDN博客已經(jīng)介紹了,但是在實(shí)際運(yùn)用于真正的文件上傳時(shí),還是有些注意事項(xiàng)需要注意的。
在進(jìn)入主題之前,首先需要簡(jiǎn)單介紹一下MultipartFile這個(gè)類,通過(guò)getOriginalFilename()獲取文件的名字,但是這個(gè)名字只是上傳文件的名字,通過(guò)這個(gè)名字是無(wú)法訪問(wèn)到這個(gè)文件的。以下是測(cè)試時(shí)的debug信息:
可以看到?MultipartFile類中,有filename,有filelocation,甚至還有臨時(shí)文件的絕對(duì)路勁和名字,但是,卻沒有接口可以獲取這些信息。也就是說(shuō),通過(guò)類MultipartFile只能獲得文件名和文件流。
再說(shuō),使用Files.probeContentType檢測(cè)上傳的MultipartFile時(shí),為什么可以正常工作。在Files.probeContentType中設(shè)置一個(gè)斷點(diǎn),可以發(fā)現(xiàn)進(jìn)入函數(shù)之后,會(huì)直接調(diào)轉(zhuǎn)到1624行,調(diào)用
FileTypeDetectors.defaultFileTypeDetector的probeContentType?通過(guò)進(jìn)一步定義跟蹤,默認(rèn)的defaultFileTypeDetector是RegistryFileTypeDetector,根據(jù)基類AbstractFileTypeDetector中probeContentType的實(shí)現(xiàn)如下:
public final String probeContentType(Path var1) throws IOException {if (var1 == null) {throw new NullPointerException("'file' is null");} else {String var2 = this.implProbeContentType(var1);if (var2 == null) {Path var3 = var1.getFileName();if (var3 != null) {FileNameMap var4 = URLConnection.getFileNameMap();var2 = var4.getContentTypeFor(var3.toString());}}return var2 == null ? null : parse(var2);}}其中,主要是implProbeContentType中實(shí)現(xiàn)對(duì)內(nèi)容類型的分析。回到RegistryFileTypeDetector的implProbeContentType函數(shù):
public String implProbeContentType(Path var1) throws IOException {if (!(var1 instanceof Path)) {return null;} else {Path var2 = var1.getFileName();if (var2 == null) {return null;} else {String var3 = var2.toString();int var4 = var3.lastIndexOf(46);if (var4 >= 0 && var4 != var3.length() - 1) {String var5 = var3.substring(var4);NativeBuffer var6 = null;NativeBuffer var7 = null;Object var9;try {var6 = WindowsNativeDispatcher.asNativeBuffer(var5);var7 = WindowsNativeDispatcher.asNativeBuffer("Content Type");String var8 = queryStringValue(var6.address(), var7.address());return var8;} catch (WindowsException var13) {var13.rethrowAsIOException(var1.toString());var9 = null;} finally {var7.release();var6.release();}return (String)var9;} else {return null;}}}}在這里可以看到文件名var2之后,就在文件名上進(jìn)行進(jìn)一步分析和判斷,沒有讀取文件。所以,默認(rèn)的detector,即使沒有實(shí)際的文件,只要根據(jù)文件名,就可以判斷一個(gè)文件的內(nèi)容類型,雖然,有時(shí)不準(zhǔn)確,例如,將一個(gè)png文件改成txt的擴(kuò)展名,分析出來(lái)的結(jié)果就是:text/plain。根據(jù)類的實(shí)現(xiàn),也可以通過(guò)加載自己實(shí)現(xiàn)的類型檢測(cè)類,然后,再調(diào)用Files.probeContentType就可以使用自己的類型探測(cè)類了。
而使用Tika調(diào)用String detect(File file)接口時(shí),如果文件不存在,就會(huì)跑出IO異常:
Tika defaultTika = new Tika();String fileType;try{final File file = new File(fileName);fileType = defaultTika.detect(file);}catch (IOException ioEx){fileType = "Unknown";}因此,在處理上傳的文件時(shí),使用MultipartFile.getOriginalFilename獲取的文件名生成一個(gè)File對(duì)象來(lái)獲取文件內(nèi)容類型,會(huì)出IOException?異常。而且將file轉(zhuǎn)成File對(duì)象時(shí),還可能會(huì)產(chǎn)生臨時(shí)文件。
不過(guò),還好的是Tika還提供了一個(gè)針對(duì)stream流的接口:String detect(String name)?
Tika defaultTika = new Tika();MultipartFile multipartFile = multipartHttpServletRequest.getFile(key);String fileType;try{InputStream stream = multipartFile.getInputStream();fileType = defaultTika.detect(stream);}catch (IOException ioEx){fileType = "Unknown";}Tika還提供了Parser,可以通過(guò)Parser對(duì)InputStream分析得到文件的內(nèi)容類型與Tika.detect(InputStream)的結(jié)果是一樣的,示例代碼如下:
public static String getMimeTypeByParser(InputStream stream) {AutoDetectParser parser = new AutoDetectParser();Metadata metadata = new Metadata();BodyContentHandler handler = new BodyContentHandler();try {parser.parse(stream, handler, metadata);} catch (IOException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (TikaException e) {e.printStackTrace();}return metadata.get(HttpHeaders.CONTENT_TYPE);}總結(jié)
以上是生活随笔為你收集整理的Java如何判断一个上传文件的内容类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: layer opcode oracle,
- 下一篇: BAT 大厂Java 面试题集锦之核心