Java如何判断一个上传文件的内容类型
關(guān)于如何判斷一個文件的類型,在如何判斷一個文件的類型_jimmyleeee的博客-CSDN博客已經(jīng)介紹了,但是在實(shí)際運(yùn)用于真正的文件上傳時,還是有些注意事項(xiàng)需要注意的。
在進(jìn)入主題之前,首先需要簡單介紹一下MultipartFile這個類,通過getOriginalFilename()獲取文件的名字,但是這個名字只是上傳文件的名字,通過這個名字是無法訪問到這個文件的。以下是測試時的debug信息:
可以看到?MultipartFile類中,有filename,有filelocation,甚至還有臨時文件的絕對路勁和名字,但是,卻沒有接口可以獲取這些信息。也就是說,通過類MultipartFile只能獲得文件名和文件流。
再說,使用Files.probeContentType檢測上傳的MultipartFile時,為什么可以正常工作。在Files.probeContentType中設(shè)置一個斷點(diǎn),可以發(fā)現(xiàn)進(jìn)入函數(shù)之后,會直接調(diào)轉(zhuǎn)到1624行,調(diào)用
FileTypeDetectors.defaultFileTypeDetector的probeContentType?通過進(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)對內(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ù)文件名,就可以判斷一個文件的內(nèi)容類型,雖然,有時不準(zhǔn)確,例如,將一個png文件改成txt的擴(kuò)展名,分析出來的結(jié)果就是:text/plain。根據(jù)類的實(shí)現(xiàn),也可以通過加載自己實(shí)現(xiàn)的類型檢測類,然后,再調(diào)用Files.probeContentType就可以使用自己的類型探測類了。
而使用Tika調(diào)用String detect(File file)接口時,如果文件不存在,就會跑出IO異常:
Tika defaultTika = new Tika();String fileType;try{final File file = new File(fileName);fileType = defaultTika.detect(file);}catch (IOException ioEx){fileType = "Unknown";}因此,在處理上傳的文件時,使用MultipartFile.getOriginalFilename獲取的文件名生成一個File對象來獲取文件內(nèi)容類型,會出IOException?異常。而且將file轉(zhuǎn)成File對象時,還可能會產(chǎn)生臨時文件。
不過,還好的是Tika還提供了一個針對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,可以通過Parser對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如何判断一个上传文件的内容类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: layer opcode oracle,
 - 下一篇: 涨姿势 - 了解各种常见的CO(CIO、