2012-08-24 47 views
0

我需要以各种方式在Java中保存一些数据,至File,至String,至System.out ......我最终用3种方法做了几乎相同的事情。所以我将它们改为一个以OutputStream作为参数的单一方法。我为一个OutputStream写了一些东西,例如一些文本,一个序列化的对象,另一个序列化的对象,一些数字数据...如何在同一个InputStream中读取不同的数据组,对每个InputStream使用不同类型的InputStream?

但现在我卡住了。我忽略了我无法区分已写入的不同事物的事实。我为数据创建了一个InputStream。我在该流上使用Scanner首先读取文本,然后尝试使用ObjectInputStream读取序列化对象,但是我得到一个EOFException

我想扫描仪预读。如何防止扫描仪预读。
或者说,我怎样才能使用适当的InputStream为每个数据读取每组数据。

+1

因此,您有一个InputStream,您想使用Scanner *和* ObjectInputStream进行读取? – aioobe

+0

是的,如果可能的话 – neXus

+1

您必须决定它是否是文本例如扫描仪或二进制例如ObjectInputStream的。如果你真的知道自己在做什么,你可以混合它们,但这不太可能是一个好主意。即它更可能是一个可怕的混乱。 –

回答

2

你真的不想尝试使用不同的阅读器从同一个流中读取。即使你设法使它在你的机器上工作,当你在不同的操作系统或不同的JVM实现上运行时,它可能会中断。

您应该选择一种读取和写入数据的方法。既然你在流中使用序列化对象,你可能最好使用它来处理所有事情。您已经在您的评论中指出,通过字符串读取二进制数据并正确解释它非常困难。但是,获取一个String对象并不难,把它写在输出流上,读回来并将其转换为一个String。

现在有解释您的数据的问题。我建议将所有内容写入标签数据对中。你首先写出一个Integer(也许是一个枚举的序号,使它们更容易在你的程序中使用),然后你写出你的数据。整数表示流中下一个数据的类型(例如Text或Object),然后读入的下一个对象是数据,您知道它是什么类型。如果是文本,则可以将对象转换为字符串,并将其传递给扫描器,如果它是对象,则只需执行任何与该对象相关的操作。

为了使事情变得更清洁,您可以使用每种数据类型的方法在流的周围构建一个包装。也许你可以有一个getNextObject()方法和一个getNextTextScanner()方法。每个人都会首先检查流中的下一个Integer标记,以确保它正在读取正确的数据(如果发现不匹配则抛出异常),然后返回下一个Object或返回一个新的Scanner来处理一串数据。

真的,如果您可以为两种不同类型的数据使用不同的流,那会更好。但是,如果你真的被困在同一个流中,那我就是这么做的。

+0

这是一个很好,清晰的答案。我试图实现这些自定义流。问题在于,据我所知,序列化只能通过ObjectOutputStream和ObjectInputStream完成。这些类的实现似乎在很大程度上依赖于JVM。他们不是纯粹的Java代码。我显然不能创造自己的行为,而不发明自己的序列化机制,我不想这样做。看来我需要在引擎盖下使用这些流。我会尽力明天开始工作。 – neXus