我尝试使用两种方式读取文件类型。它在使用 ByteArrayInputStream
但不是 FileInputStream
将 FileInputStream
与 URLConnection
一起使用,
String fileType = URLConnection
.guessContentTypeFromStream(
new FileInputStream(new File("C:\\image.jpeg"))
); //fileType = null
使用 ByteArrayInputStream
和 URLConnection
String fileType = URLConnection
.guessContentTypeFromStream(
new ByteArrayInputStream(Files.readAllBytes(new File("C:\\image.jpeg").toPath()))
); //fileType = image/jpeg
为什么结果不同?
另外,有没有提到只使用 ByteArrayInputStream
来读取文件类型?
最佳答案
URLConnection.guessContentTypeFromStream
的技术是查看第一个字节,即所谓的 magic cookie 来识别文件。
实现者选择让 Stream 保持不变状态,因此继续阅读将从(再次)开始。
为此,它对先前标记的流位置(实际开始)执行 reset():
。
static public String guessContentTypeFromStream(InputStream is)
throws IOException {
// If we can't read ahead safely, just give up on guessing
if (!is.markSupported())
return null;
is.mark(16);
int c1 = is.read();
int c2 = is.read();
int c3 = is.read();
...
int c14 = is.read();
int c15 = is.read();
int c16 = is.read();
is.reset();
....
对于顺序 FileInputStream markSupported()
返回默认值 false
。
可以通过用 BufferedInputStream
包装 FileInputStream
来解决它,无论如何这样会更快。
String fileType = URLConnection
.guessContentTypeFromStream(
new BufferedInputStream(Files.newInputStream(Paths.get("C:\\image.jpeg")))
);
请注意,javadoc 中所述的 Files.newInputStream
将不支持标记要重置的位置。
(使用 ByteArrayInputStream
开销太大。)
关于java - FileInputStream 和 ByteArrayInputStream 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52818282/