问题
I needed to save some data in Java in various ways, to a File
, to a String
, to System.out
... And I ended up with 3 methods doing pretty much the same thing. So I changed them into a single method with an OutputStream
as a parameter. I wrote a few things to a single OutputStream, e.g. some text, a serialized object, another serialized object, some numerical data ...
But now I'm stuck. I overlooked the fact that I cannot distinguish between the different things that have been written. I create an InputStream
for the data. I use a Scanner
on that stream to read the text first, and then I tried using an ObjectInputStream to read the serialized objects, but I get an EOFException
.
I guess that the Scanner reads ahead. How can I prevent the scanner to read ahead.
Or rather, how can I read each group of data using an appropriate InputStream for each of them.
回答1:
You really don't want to try using different readers to read from the same stream. Even if you manage to get it working on your machine, it might break when you run it on a different OS or with a different JVM implementation.
You should choose a single method of reading and writing data. Since you're using serialized objects in the stream you're probably best off using that for everything. You already pointed out in your comments that it would be very difficult to read binary data in through a string and interpret it correctly. However, it's not hard to take a String object, write it out on the output stream, read it back in and cast it as a String.
Now there's the problem of interpreting your data. I suggest writing everything out in tag-data pairs. You write out an Integer first (maybe the ordinal of an enum to make them easier to use in your program), then you write out your data. The integer represents the type of data that's coming next in the stream (e.g. either Text or Object), and then the next object you read in is the data and you know what type it is. If it is Text you can cast the object to a String, and pass it into a Scanner, and if it's an object then you just do whatever you need to do with the object.
To make things a bit cleaner you could build a wrapper around the stream with a method for each data type. Maybe you could have a getNextObject()
method and a getNextTextScanner()
method. Each would first check the next Integer tag in the stream to make sure it's reading the right data (throwing an exception if it finds a mismatch), and then would either return the next Object or return a new Scanner for processing a String of data.
Really, it would be better if you could use separate streams for the two different types of data. But, if you're really stuck using the same stream then that's how I'd do it.
来源:https://stackoverflow.com/questions/12110523/how-can-i-read-different-groups-of-data-on-the-same-inputstream-using-different