Java 缓冲输入流标记读取限制

Java 缓冲输入流标记读取限制,java,inputstream,Java,Inputstream,我正在学习如何使用输入流。我尝试将mark用于BufferedInputStream,但当我尝试重置时,出现以下异常: java.io.IOException: Resetting to invalid mark 我想这意味着我的标记读取限制设置错误。我实际上不知道如何设置mark()中的读取限制。我试着这样做: is = new BufferedInputStream(is); is.mark(is.available()); 这也是错误的 is.mark(16); 这也会引发相同的异常

我正在学习如何使用输入流。我尝试将mark用于BufferedInputStream,但当我尝试重置时,出现以下异常:

java.io.IOException: Resetting to invalid mark
我想这意味着我的标记读取限制设置错误。我实际上不知道如何设置mark()中的读取限制。我试着这样做:

is = new BufferedInputStream(is);
is.mark(is.available());
这也是错误的

is.mark(16);
这也会引发相同的异常。
我如何知道我应该设置的阅读限制?因为我将从输入流中读取不同大小的文件

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

如果您需要检查已读取的数据以外的几个字节来决定下一步要做什么,则标记
有时很有用,然后重置回标记,并调用期望文件指针位于输入逻辑部分开头的例程。我不认为它真的是为了其他什么

如果你看一下javadoc,它说

标记操作会记住输入流中的一个点,重置操作会导致在从包含的输入流中获取新字节之前,重新读取自最近的标记操作以来读取的所有字节


这里要记住的关键一点是,一旦在流中标记一个点,如果继续读取超出标记长度的内容,标记将不再有效,,重置调用将失败。因此,mark适用于特定情况,在其他情况下用处不大。

这将从同一个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();
}

用于(int i=0;我个人的想法?不要使用mark-虽然我肯定有一个,但我还没有找到一个好的理由。通常情况下,这是一个处理不善的信号。我倾向于认为流不是流,除非我处理的是它最原始的形式。我宁愿在它周围有一个紧密的包装,以获取它的信息和包它启动,并将该软件包发送到应用程序中的某个地方进行处理。@glowcoder感谢您的评论。正如我前面所说,我对InputStream是一个新手。我实际上尝试过两次使用InputStream。我认为这是一种方法。设置mark和reset。您对如何实现这一点有其他建议吗?mark就是这样工作的。让我们来看看假设您的输入流最终是
abcde
。您目前正在处理
abe
。(请记住,您还不知道“下游”是什么。)您标记它。然后您再阅读一些,得到
cde
。您看着它,出于任何原因说“等等,我不能在这种模式下处理
cde
”。您这么说“我真的希望我能再次回到process
cde
,你可以这样做,因为你
mark()
ed了它。你只需
reset()
将流放回标记它时的位置,你就可以像以前一样重新阅读它。所以当你说“我想使用输入流两次”时”你能澄清一下你想做什么吗?我相信社区可以想出一些东西(代码示例,或者至少是指导)为了帮助您实现目标。@glowcoder情况就是这样。我有一个输入流。apache POI首先会使用它读取文档属性。然后会使用相同的输入流再次读取并存储文档。问题是。apache POI获取输入流后,文档会被存储,但大小为0。我想这是因为输入流以前被读取过。谢谢你的评论。当你说“如果你继续读取,缓冲区需要重新填充”时。这是因为我使用了BufferedInputStream吗?是的,但是,未缓冲的io流不支持标记和重置。谢谢你的回答,我正计划将其重置为beginning。但现在我认为这不是一个好主意。当你说我应该将它复制到临时文件时,你的意思是我需要在使用它之前先将它存储在我的文件夹中吗?@NurAini-是的,创建一个临时文件,将流复制到其中,然后你可以根据需要多次重新读取该临时文件。