在项目中有这么一个需求:判断上传文件的类型,考虑两种方案:
2. 使用URLConnection.guessContentTypeFromStream通过文件前16个字节推断;
?
第一种方法显然不够严谨(文件名可随意更改),于是采用 了第二种方案
?
class="java">// some code FileInputStream inputFile = new FileInputStream("D:/test.pdf"); String mime = URLConnection.guessContentTypeFromStream(inputFile); // save to mongodb......
?
一周后,偶然发现所有上传的文件在mongo中mine字段均为空,翻读guessContentTypeFromStream方法源码有一处判断引起了我的注意:
?
?
markSupported ? 似有所悟,翻阅JDK文档后一切拨云见日:
?
markSupported public boolean markSupported() Tests if this input stream supports the mark and reset methods. Whether or not mark and reset are supported is an invariant property of a particular input stream instance. The markSupported method of InputStream returns false. Returns: true if this stream instance supports the mark and reset methods; false otherwise. See Also: mark(int), reset()
?
?
首先介绍一下InputStream类提供的mark与reset方法:
?在该输入流中使用mark标记当前位置,后续调用 reset 方法重新将流定位于最后标记位置,以便后续读取。?
?
?markSupported方法可以判断当前类是否具有mark与reset方法的能力,只有重写了mark与reset方法,markSupported才会返回true。前面展示的代码使用的FileInputStream没有重写父类InputStream的这两个方法,其不具有mark和reset方法的能力,使用BufferInputStream替换FileInputStream可解决此问题:FileInputStream inputFile = new FileInputStream("D:/t1.png"); System.out.println("FileInputStream mime:" + URLConnection.guessContentTypeFromStream(inputFile)); System.out.println("BufferedInputStream mime:" + URLConnection.guessContentTypeFromStream(new BufferedInputStream(inputFile))); print result: FileInputStream mime:null BufferedInputStream mime:image/png
?
?