我尝试使用两种方式读取文件类型。它在使用ByteArrayInputStream时工作,但不使用FileInputStream。
使用FileInputStream和URLConnection,
String fileType = URLConnection
.guessContentTypeFromStream(
new FileInputStream(new File("C:\\image.jpeg"))
); //fileType = nullByteArrayInputStream与URLConnection的结合
String fileType = URLConnection
.guessContentTypeFromStream(
new ByteArrayInputStream(Files.readAllBytes(new File("C:\\image.jpeg").toPath()))
); //fileType = image/jpeg为什么结果是不同的?另外,是否有任何地方提到只使用ByteArrayInputStream读取文件类型?
发布于 2018-10-15 14:22:20
URLConnection.guessContentTypeFromStream的技术是查看第一个字节,也就是所谓的神奇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。
我们可以通过用一个FileInputStream包一个BufferedInputStream来解决这个问题,这样无论如何都会更快。
String fileType = URLConnection
.guessContentTypeFromStream(
new BufferedInputStream(Files.newInputStream(Paths.get("C:\\image.jpeg")))
);注意,javadoc中所述的Files.newInputStream不支持标记重置位置。
(使用ByteArrayInputStream会带来太大的开销。)
发布于 2018-10-15 14:21:56
虽然这两种输入流类型在许多方面不同,但造成这种行为的原因仅与这两种流的标记/重置支持有关。
如果您检查URLConnection.guessContentTypeFromStream的来源,您会注意到:
// If we can't read ahead safely, just give up on guessing
if (!is.markSupported())
return null;ByteArrayInputStream重写markSupported以返回true,而FileInputStream继承了返回false的默认InputStream.markSupported方法。
换句话说,guessContentTypeFromStream不能处理文件输入流(或任何不支持标记/重置的流)。
https://stackoverflow.com/questions/52818282
复制相似问题