I am trying to read 2 arraylists using the following methods.
public static ArrayList<Contestant> readContestantsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Contestant> contestants = (ArrayList<Contestant>) ois.readObject();
ois.close();
return contestants;
}
public static ArrayList<Times> readContestantsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<times> times = (ArrayList<Times>) ois.readObject();
ois.close();
return times;
}
Bit this doesn't work. It cannot cast to the the second arraylist type i've saved. So how can I access this? The exact error I got was this:
Exception in thread "main" java.lang.ClassCastException: com.deanchester.minos.model.Contestant cannot be cast to com.deanchester.minos.model.Times
at com.deanchester.minos.tests.testAddTime.main(testAddTime.java:31)
The line that this is referring to is:
ArrayList<times> times = (ArrayList<Times>) ois.readObject();
So how can I read 2 different arraylists from one file?
Use FileOutputStream fos = new FileOutputStream("minos.dat", true); when writing the second file. true is a value of argument "append". Otherwise you override the file content. This is the reason that you read the same collection twice.
When you are reading the second collection from the file you have to skip to the beginning of the second collection. To do this you can remember how many bytes have you read on first phase and then use method skip().
But better solution is to open file only once (I mean call new FileInputStream and new FileOutputStream) only once and then pass it to methods that read collections.
You can read two different objects from a file using a ObjectInputStream, but your problem comes from the fact that you reopen the stream so it starts at the beginning of the file where you have the ArrayList<Contestant> and then you ArrayList<Times>. Try doing everything at once and returning both lists:
public static ContestantsAndTimes readObjectsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Contestant> contestants = (ArrayList<Contestant>) ois.readObject();
ArrayList<Times> times = (ArrayList<Times>) ois.readObject();
ois.close();
return new ContestantsAndTimes(contestants, times);
}
Related
This question already has answers here:
How can I quickly load a large txt file into BigInteger?
(3 answers)
Closed 5 years ago.
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// Load file with 17 million digit long number
BufferedReader Br = new BufferedReader (new FileReader("test2.txt"));
String Line = Br.readLine();
try {
// create a new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("test.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
// write the number into a new file
oout.writeObject(Line);
// close the stream
oout.close();
// create an ObjectInputStream for the new file
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt"));
// convert new file into a BigInteger
BigInteger Big = (BigInteger) ois.readObject();
} catch (Exception ex) {
ex.printStackTrace();
}
}
This is a program I made for learning how to use Input/OutputStream. Everything works except that I get an error when trying to turn my file into a BigInteger.
java.lang.String cannot be cast to java.math.BigInteger
at ReadOutPutStream.main
I'm new to this so I'm probably making a simple error, what am I doing wrong?
You wrote a string to the file with
oout.writeObject(Line);
Therefore when you read an object from the stream it will also be a String. You can't cast a String to a BigInteger so you get an exception. I know form your earlier question that you want to serialize the BigInteger to save time when deserializing from the filesystem, so to fix your specific problem you should write a BigInteger to the stream instead of a string:
oout.writeObject(new BigInteger(Line));
I'm testing the ObjectInputStream and ObjectOutputStream classes
tried to warp both in buffered stream object ..
File file = new File("file.lel"); //Assuming the file exist and has data stored in it.
//will truncate file
try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))) //Bad Practice!
) {
SomeObject writeMe = new SomeObject(1, 2, 3, 50.5, 'k'); //Object with 3 ints, a double and a char
final double D = 30.3; //for testing
out.writeDouble(D);
out.writeObject(writeMe);
out.flush();
double DAgain = in.readDouble();
SomeObject readMe = (SomeObject)in.readObject();
readMe.printInfo();
}
//Some catch blocks...
But i'm getting EOFException on line 3 in the code above
Exception in thread "main" java.io.EOFException //header loaded first .. ?!
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
When i removed the buffer stream objects, code worked .. i.e.
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))
) { ... }
Why this behavior? any idea?
Firstly, don't do this. Don't try to initialize the input stream until you've got data in the file.
As for why it's working when you don't buffer, I believe the problem is with the buffering of the output stream... in the buffered version, you're creating the FileOutputStream which will truncate the file, then wrapping that in a BufferedOutputStream, then wrapping that in an ObjectOutputStream. The last of these will write the preamble data to the stream - but it only gets as far as the BufferedOutputStream which buffers the data. When you try to create an ObjectInputStream reading from the file, it's trying to read the preamble... but there's nothing to read.
You can demonstrate this easily:
import java.io.*;
class Test {
public static void main(String[] args) throws IOException {
// Not disposing of any resources just for simplicity.
// You wouldn't actually use code like this!
FileOutputStream fos = new FileOutputStream("data");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
// Flush the preamble to disk
bos.flush();
FileInputStream fis = new FileInputStream("data");
ObjectInputStream ois = new ObjectInputStream(fis);
}
}
Without the flush() call, you get the the exception you've seen - with it, there's no exception.
As I say though, you simply shouldn't do this in the first place, IMO.
In my Android application I'm trying to store a Map structure such as:Map<String, Map<String, String>>using internal storage. I've looked into using SharedPreferences, but as you know, this only works when storing primitive data types. I tried to use FileOutputStream, but it only lets me write in bytes...Would I need to somehow serialize the Hashmap and then write to file?
I've tried reading through http://developer.android.com/guide/topics/data/data-storage.html#filesInternal but I can't seem to find my solution.
Here's an example of what I'm trying to do:
private void storeEventParametersInternal(Context context, String eventId, Map<String, String> eventDetails){
Map<String,Map<String,String>> eventStorage = new HashMap<String,Map<String,String>>();
Map<String, String> eventData = new HashMap<String, String>();
String REQUEST_ID_KEY = randomString(16);
. //eventData.put...
. //eventData.put...
eventStorage.put(REQUEST_ID_KEY, eventData);
FileOutputStream fos = context.openFileOutput(EVENT_FILENAME, Context.MODE_PRIVATE);
fos.write(eventStorage) //This is wrong but I need to write to file for later access..
}
What is the best approach for storing this type of a data structure internally in an Android App? Sorry if this seems like a dumb question, I am very new to Android. Thanks in advance.
HashMap is serializable, so you could just use a FileInputStream and FileOutputStream in conjunction with ObjectInputStream and ObjectOutputStream.
To write your HashMap to a file:
FileOutputStream fileOutputStream = new FileOutputStream("myMap.whateverExtension");
ObjectOutputStream objectOutputStream= new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(myHashMap);
objectOutputStream.close();
To read the HashMap from a file:
FileInputStream fileInputStream = new FileInputStream("myMap.whateverExtension");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myNewlyReadInMap = (HashMap) objectInputStream.readObject();
objectInputStream.close();
+1 for Steve P's answer but it does not work directly and while reading I get a FileNotFoundException, I tried this and it works well.
To Write,
try
{
FileOutputStream fos = context.openFileOutput("YourInfomration.ser", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myHashMap);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
And to Read
try
{
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"/FenceInformation.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
}
catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
Writing:
FileOutputStream fos = context.openFileOutput(EVENT_FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream s = new ObjectOutputStream(fos);
s.writeObject(eventStorage);
s.close();
Reading is done in the inverse way and casting to your type in readObject
My teacher said that in file server program ObjectInputStreamReader is compulsory to write. When I asked the reason then he said me it is comfortable for file server program. I am thinking that it is not necessary reason. Why InputStreamReader or other alternatives can not be used? what is the advantage of ObjectInputStreamReader over InputStreamReader.
Here code for client/server:
public class Client {
public static void main(String[] args) {
Socket s = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
Scanner sc = new Scanner(System.in);
String data = "";
try {
s = new Socket("localhost", 1234);
System.out.println("client is connectd");
ois = new ObjectInputStream(s.getInputStream());
String jai = (String) ois.readObject();
System.out.println("DATA from SERVER:" + jai);
oos = new ObjectOutputStream(s.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Enter file name:");
try {
String fil = (String) sc.next();
OutputStream pw = new FileOutputStream(fil + ".new");
oos.writeObject(fil);
data = (String) ois.readObject();
pw.write(data.getBytes());
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Content of file:" + data);
}
}
Can any one say what is actual reason ?
I think you mean ObjectInputStream and BufferedInputStream (not readers).
ObjectInputStream wraps input stream and provides typed methods that allow reading data of certain type from the stream. For example readDouble(), readObject() etc.
BufferedInputStream does not provide additional API (comparing to regular InputStream). The only thing it does is buffering of data, i.e. it reads data chunk-by-chunk that is much more efficient way than reading byte-by-byte.
An InputStream is an abstract class that can be used to define any type of input stream, including reading from file systems, URLs, sockets, etc.
You don't actually create an InputStream, as it doesn't mean anything by itself. Rather, you create a type of InputStream that defines how to read/write a particular type of data, such as the suggested ObjectInputStream. This class defines that the data being written is a Java Object (that implements Serializable or Externalizable). There are other InputStreams that are used for generic file data, images, audio, and a whole range of other types.
There is no such thing as an ObjectInputStreamReader, unless you write a class like this yourself that has the purpose of writing to an ObjectInputStream.
Refer to the ObjectInputStream and InputStream Java docs for more enlightenment
I'm a newbie in Java so I'm not sure if this is possible. Basically I need to de-serialise a file into an object of a given type. Basically the method will do this:
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
MyClass newObject = (MyClass)in.readObject();
in.close();
return newObject;
I would like this method to be generic, therefore I can tell it what type I want to in.readObject() to cast its output into, and return it.
Hope this makes sense...then again, I probably didn't understand generics properly and this is not actually possible, or advisable.
Thanks,
D.
I'm not sure about Android (or any limitations it might have), but in Java you can do something like this:
public static <T> T getObject(String filename) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
T newObject = (T) in.readObject();
in.close();
return newObject;
}
and then call it like
MyClass myObj = getObject("in.txt");
This will give you an unchecked cast warning though, since the compiler can't be sure you can cast the object received to the type provided, so it's not exactly type safe. You need to be sure that what you're getting from the input stream actually can be cast to that class, otherwise you will get a ClassCastException. You can suppress the warning by annotating the method with #SuppressWarnings("unchecked")
Having just seen this How do I make the method return type generic? I am going to try the following:
public <T> T deserialiseObject(String filename, Class<T> type)
throws StreamCorruptedException, IOException,
ClassNotFoundException {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
Object newObject = in.readObject();
in.close();
return type.cast(newObject);
}