2011-12-22 39 views
10

我正在学习如何使用InputStream。我试图用大关的BufferedInputStream,但是当我尝试重置我有这些异常:缓冲输入流标记读取限制

java.io.IOException: Resetting to invalid mark 

我想这意味着我的标记读取限制设置错误。实际上我不知道如何在mark()中设置读取限制。我试过像这样:

is = new BufferedInputStream(is); 
is.mark(is.available()); 

这也是错误的。

is.mark(16); 

这也引发同样的异常。 我如何知道我应该设置的读取限制?因为我将从输入流中读取不同的文件大小。

+2

我的个人需要?不要使用标记 - 虽然我确定有标记,但我还没有找到一个好的理由。通常情况下,这首先是处理不善的一个标志。我倾向于认为流不是流,除非我正在处理它最原始的形式。我宁愿紧紧包装它,以获取其信息,将其打包,然后将该包发送到应用程序的某处进行处理。 – corsiKa 2011-12-22 03:54:48

+0

@glowcoder感谢您的评论。正如我前面所说,我是使用InputStream的新手。实际上我试图使用输入流两次。我认为这是做到这一点的方法。设置标记和重置。你有没有其他建议如何实现这一目标? – 2011-12-22 04:05:57

+3

马克是这样工作的。假设您的输入流最终会成为“A B C D E”。你到目前为止处理'A B'。 (记住,你不知道什么是'下游')。你标记它。然后再阅读一些内容,就会得到'C D E'。你看看它,然后说:“等等,我不能在这种模式下处理'C D E'!”无论出于何种原因所以你说:“我真的希望我可以再次处理'C D E'......你可以,因为你'编辑'它。您只需将reset()放回原来的位置即可,您可以像以前那样再次读取它。 – corsiKa 2011-12-22 06:06:02

回答

0

您传递给mark()的数值是您需要重置的数量。如果您需要重置到流的开头,则需要与整个流一样大的缓冲区。这可能不是一个很好的设计,因为它不会很好地适应大型流。如果你需要两次读取流而你不知道数据的来源(例如,如果它是一个文件,你可以重新打开它),那么你应该把它复制到临时文件中,随意阅读。

+0

感谢您的回答,我正计划将其重置为开始。但现在我认为它不是一个好主意。当你说我应该将它复制到临时文件中时,是否意味着我需要先将它存储在我的文件夹中的某个位置,然后再使用它? – 2011-12-22 07:44:54

+0

@NurAini - 是的,创建一个临时文件,将流复制到它中,然后您可以根据需要多次重新读取该临时文件。 – jtahlborn 2011-12-22 15:15:46

6

mark有时可用,如果您需要检查超出您所读取的几个字节以决定下一步该做什么,那么您重置回标记并调用期望文件指针处于开始位置的例程该输入的逻辑部分。我不认为这真的是其他的意图。

如果你看的javadoc BufferedInputStream它说

标记操作输入流中的记忆点和复位操作导致,因为最新的标记操作中读取的所有字节之前新被重读字节从包含的输入流中获取。

这里要记住的关键事情是,一旦你标记流中的一个点,如果你继续读超出了显着的长度,该商标将不再有效,并重置通话将失败。所以标记对于特定情况是有利的,在其他情况下没有太多用处。

+0

感谢您的评论。当你说'如果你继续阅读并且需要重新填充缓冲区'。这是因为我用BufferedInputStream吗? – 2011-12-22 07:35:21

+0

是的,但是,无缓冲的io流不支持标记和重置。 – Bill 2011-12-22 13:18:42

1

这将从相同的BufferedInputStream中读取5次。

for (int i=0; i<5; i++) { 
    inputStream.mark(inputStream.available()+1); 
    // Read from input stream 
    Thumbnails.of(inputStream).forceSize(160, 160).toOutputStream(out); 
    inputStream.reset(); 
}