首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FileInputStream与ByteArrayInputStream的区别

FileInputStream与ByteArrayInputStream的区别
EN

Stack Overflow用户
提问于 2018-10-15 13:50:33
回答 2查看 736关注 0票数 1

我尝试使用两种方式读取文件类型。它在使用ByteArrayInputStream时工作,但不使用FileInputStream

使用FileInputStreamURLConnection

代码语言:javascript
复制
String fileType = URLConnection
  .guessContentTypeFromStream(
    new FileInputStream(new File("C:\\image.jpeg"))
   ); //fileType = null

ByteArrayInputStreamURLConnection的结合

代码语言:javascript
复制
String fileType = URLConnection
.guessContentTypeFromStream(
  new ByteArrayInputStream(Files.readAllBytes(new File("C:\\image.jpeg").toPath()))
 ); //fileType = image/jpeg

为什么结果是不同的?另外,是否有任何地方提到只使用ByteArrayInputStream读取文件类型?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-15 14:22:20

URLConnection.guessContentTypeFromStream的技术是查看第一个字节,也就是所谓的神奇cookie来识别文件。

实现者选择将Stream保持在未更改的状态,因此继续读取将在开始时(再次)开始。

为此,它对前面标记的流位置(实际开始)执行reset():

代码语言:javascript
复制
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来解决这个问题,这样无论如何都会更快。

代码语言:javascript
复制
String fileType = URLConnection
    .guessContentTypeFromStream(
        new BufferedInputStream(Files.newInputStream(Paths.get("C:\\image.jpeg")))
     );

注意,javadoc中所述的Files.newInputStream不支持标记重置位置。

(使用ByteArrayInputStream会带来太大的开销。)

票数 3
EN

Stack Overflow用户

发布于 2018-10-15 14:21:56

虽然这两种输入流类型在许多方面不同,但造成这种行为的原因仅与这两种流的标记/重置支持有关。

如果您检查URLConnection.guessContentTypeFromStream的来源,您会注意到:

代码语言:javascript
复制
// 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不能处理文件输入流(或任何不支持标记/重置的流)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52818282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档