We have an application which requires us to read data from a file (.dat) dynamically using deserialization. We are actually getting first object and it throws null pointer exception and "java.io.StreamCorruptedException:invalid type code:AC" when we are accessing other objects using a "for" loop.
File file=null;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
ObjectOutputStream oos=null;
try{
file=new File("account4.dat");
fos=new FileOutputStream(file,true);
bos=new BufferedOutputStream(fos);
oos=new ObjectOutputStream(bos);
oos.writeObject(m);
System.out.println("object serialized");
amlist=new MemberAccountList();
oos.close();
}
catch(Exception ex){
ex.printStackTrace();
}
Reading objects:
try{
MemberAccount m1;
file=new File("account4.dat");//add your code here
fis=new FileInputStream(file);
bis=new BufferedInputStream(fis);
ois=new ObjectInputStream(bis);
System.out.println(ois.readObject());
**while(ois.readObject()!=null){
m1=(MemberAccount)ois.readObject();
System.out.println(m1.toString());
}/*mList.addElement(m1);** // Here we have the issue throwing null pointer exception
Enumeration elist=mList.elements();
while(elist.hasMoreElements()){
obj=elist.nextElement();
System.out.println(obj.toString());
}*/
}
catch(ClassNotFoundException e){
}
catch(EOFException e){
System.out.println("end");
}
catch(Exception ex){
ex.printStackTrace();
}
After you read an object from the input stream, the stream points to the next object.
Try (without reading from ois before):
MemberAccount m1 = null;
while( (m1=ois.readObject()) != null){
System.out.println(m1.toString());
}
The grammar for serialized objects is defined as:
stream:
magic version contents
By using the append option (new FileOutputStream(file,true);) you create a file with this data:
stream:
magic version contents magic version contents magic version contents ....
This data does not conform to the specification and can't be decoded by ObjectInputStream.
Related
It throws eof exception in line 10 when I execute the following code. It seems that it cannot execute the readLong method. What should I do?
try (DataOutputStream dataOutputStream=new DataOutputStream(new BufferedOutputStream(new
FileOutputStream("1.dat")));
DataInputStream dataInputStream=new DataInputStream(new BufferedInputStream(new
FileInputStream("C:\\Users\\Asus\\IdeaProjects\\Example" +
"\\1.dat")))){
dataOutputStream.writeLong(123);
dataOutputStream.writeChar('D');
dataOutputStream.writeUTF("Hello!");
System.out.println(dataInputStream.readLong());//exception occurse here
System.out.println(dataInputStream.readChar());
System.out.println(dataInputStream.readUTF());
}catch (IOException e){
e.printStackTrace();
}
the problem you are reading the file before writing on it. when you read the file it was empty. also the data are not saved to the file until the stream is closed. so if you want to read the written values you should close the input stream and then read the file.
also be careful that the output stream file path is different than the input stream
here an example:
try ( DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("1.dat")))) {
dataOutputStream.writeLong(123);
dataOutputStream.writeChar('D');
dataOutputStream.writeUTF("Hello!");
dataOutputStream.close();
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream("1.dat")));
System.out.println(dataInputStream.readLong());
System.out.println(dataInputStream.readChar());
System.out.println(dataInputStream.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
I tried below code to write a map into file and read it:
#After
public void init(Scenario scenario){
hm.put(testNames,scenario.getStatus());
// to write code into file
try {
File fileOne=new File("file.txt");
FileOutputStream fos=new FileOutputStream(file,true);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(hm);
oos.flush();
oos.close();
fos.close();
;
} catch(Exception e) {}
}
//to read the file(in other java program)
try {
File toRead=new File("file.txt");
FileInputStream fis=new FileInputStream(toRead);
ObjectInputStream ois=new ObjectInputStream(fis);
HashMap<String,io.cucumber.java.Status> mapInFile=(HashMap<String,io.cucumber.java.Status>)ois.readObject();
ois.close();
fis.close();
for(Map.Entry<String,io.cucumber.java.Status> m :mapInFile.entrySet()){
System.out.println(m.getKey()+" : "+m.getValue());
}
The code to write to file is wrapped in #After.
I am able to write into file but getting only 1 key value pair as O/P
I have stored multiple objects in Teacher ArrayList and I'm trying to deserialize it, but it shows the garbage value.
public void Write(){
try{
FileOutputStream fs=new FileOutputStream("S.txt");
ObjectOutputStream os=new ObjectOutputStream(fs);
os.writeObject(teachers);
os.close();
}catch(Exception e)
{System.out.println(e);}
}
public void Read(){
try
{
FileInputStream fis = new FileInputStream("E:\\Books\\OOP\\Teacher\\S.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
teachers = (ArrayList<Teacher>) ois.readObject();
for(Teacher i: teachers){
System.out.println(i.toString());
}
ois.close();
fis.close();
}catch(IOException ioe){
System.out.println("Error");
return;
}catch(ClassNotFoundException c){
System.out.println("Class not found");
return;
}
}
You are using object streams, which persist your serialized objects in binary, regardless of the extension of the file (which happens to be ".txt" here, ambiguously suggesting that it'll be a text file when written).
You cannot view anything human-like from your file with a text editor when the data written is binary data.
If your "garbage values" also get printed when you iterate your List<Teacher> upon de-serialization, it implies that:
(De-)serialization actually succeeded (i.e. you've written your List<Teacher> to file and retrieved it)
Your Teacher class might not override toString properly or at all, so it prints the Type#hashCode notation from Object#toString when fed to the system output print stream
Hi im trying to save my ArrayList of objects to a file when onPause() and/or onStop() are called and then have the arrayList read from that file after the app has been killed and relaunched. Ive tried a load of different methods but none seem to work, currently this is what I have.
my code to Write :
try{
FileOutputStream fout = openFileOutput(FILENAME, 0);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(toDos);
oos.close();
}
catch (Exception e){
e.printStackTrace();
}
My code to Read :
try{
FileInputStream streamIn = openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(streamIn);
if(ois.readObject() != null) {
list = (ArrayList<Object>) ois.readObject();
ois.close();
}
}
catch (Exception e){
e.printStackTrace();
}
"FILENAME" is a variable that holds the string "data.txt"
toDos is the name of the arrayList, it is a field at the top of the Activity, it is an ArrayList of object Object which is Serializable.
Not sure what im doing wrong here, and I cant tell if its writing at all or not or where the issue might be.
You are getting an EOFException because you are reading in the object twice; once when you're checking the if statement, and once again inside the if statement. Change your code to something like this:
FileInputStream streamIn = openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(streamIn);
ToDoObject tmp = (ArrayList<ToDoObject>) ois.readObject();
ois.close();
if(tmp != null) {
toDos = tmp;
}
This code accomplishes the same thing but reads from the file a single time.
I'm trying to write a Java Android program that can read and write to a file. I'm having some issues though. When the line at the very end is run, Eclipse tells me that my totalString variable may not have been initialized. However, I assign it a value inside the try loop. When I remove that last line and run my program, my console displays "Read File Successfully", as well as "java.io.FileInputStream#d77ffd1". That's definitely not the value I wrote to the file. I don't know what I'm doing wrong here and I'm kind of losing my mind lmao. Additionally, if I try to put a line like
totalString = "A Test Value"
In the try block, I still get the same error. Any help would be greatly appreciated.
//lets try WRITING the file
Context context = getApplicationContext();
String filename = "balance";
String balanceString = "0.00";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(balanceString.getBytes());
outputStream.close();
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Writing File.");
}
//lets try READING the file
String totalString;
FileInputStream inputStream;
try {
inputStream = openFileInput(filename);
inputStream.read();
inputStream.close();
totalString = inputStream.toString();
System.out.println("Read File Successfully");
System.out.println(totalString);
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Reading File.");
}
System.out.println(totalString);
inputStream.toString() returns a string representing the id of the InputStream object. Not the data inside the file.
If you want the data inside the File which you are reading from the InputStream, you need to use built-in methods to read the file. The easiest way to do so is to wrap the InputStream object inside a BufferedReader (or any other Reader object), then use the .readLine() (or equivalent) method to get the data.
For example:
String totalString;
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(openFileInput(filename)));
totalString = in.readLine();
in.close();
System.out.println("Read File Successfully");
System.out.println(totalString);
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Reading File.");
}
Now for output:
You could use the exact same technique as before, only changing the objects to their 'Writer' equivalents. For example:
PrintWriter out;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(penFileOutput(filename, Context.MODE_PRIVATE))));
out.println(balanceString);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Writing File.");
}
The purpose of using the PrintWriter here in addition to the BufferedWriter is because it provides very easy to use methods (i.e. println()). Also, the 'flush()' method is used to make sure all the data in the stream gets written to the file, rather than 'getting stuck' in the buffer.
EDIT: Forgot to add a 'new' before the BufferedReader above. Fixed.
inputStream.read() MIGHT throw an Exception. In this case, the variable MIGHT not have be initialized. Just change the declaration to
String totalString = null;
Alternatively you can move the System.out.println to the end of the try-block, where, when reached because no Exception is thrown, the variable is initialized.
Also, read some tutorials about reading and writing files.
inputStream.read() will read a byte from the stream. But if you don't assign the return value of that function to a variable, it is discarded.
inputStream.toString() does what it says. It tries to describe the object, not the contents of the stream.
I would do it like that
FileOutputStream outputStream=new FileOutputStream(filename);
ObjectOutputStream stringSaver = new ObjectOutputStream(outputStream);
stringSaver.writeObject(balanceString);
stringSaver.close();
outputStream.close();
All this in a try catch for saving in a file the String then load it with
FileInputStream inputStream = new FileInputStream(filename);
ObjectInputStream objectStream = new ObjectInputStream(inputStream);
totalString = (String) objectStream.readObject();
objectStream.close();
inputStream.close();
this also in try catch...
It should work.
The problem solves that there was one variable may not have been initialized.
When you dont understand one part of the code be free to ask :D