writing and reading objects

M

Madhur Ahuja

Hello

I have been given the task of doing simple file handling in java.
i.e. I want to write set of records to a file and read them.
The problem is that writeObject function produces inconsistent
results when we write a series of records in one session and when
we write same number of records by running the program again and again
i.e. appending.
The file size differs in above 2 cases.

Thus reading the records produces this exception:
StreamCorruptedException

This exception occurs only when we read from the file in which data
has been appended.
The exception doesnt occurs if we write to file only once and then read.

The code that am using is:
////////////////////////////
import java.io.*;
public class serial6
{
FileOutputStream fos = null;
FileInputStream fis = null;
ObjectOutputStream oos = null;
public serial6()
{
try
{
MyClass1 obj1 = new MyClass1("sasas",12);
MyClass1 obj2 = new MyClass1("d",12);
try


fis = new FileInputStream("serial133.txt");
fis.close();
fos = new FileOutputStream("serial133.txt",true);
}
catch(FileNotFoundException e)
{
fos = new FileOutputStream("serial133.txt");

}
oos = new ObjectOutputStream(fos);
oos.writeObject(obj1);
oos.writeObject(obj2);
}
catch( IOException e)
{
}

try
{
oos.close();
} catch(IOException e) {

}
}

public serial6(int i)
{
try
{

FileOutputStream fos1 = new FileOutputStream("serial33.txt",true);
} catch(IOException e) {
}
}


public static void main(String args[])


serial6 sr = new serial6(1);
serial6 sr1 = new serial6();
}
}


class MyClass1 extends Object implements Serializable
{

String name;
int roll;
MyClass1(String a,int b)
{
this.name=a;
this.roll=b;

}
}





--
Winners dont do different things, they do things differently.

Madhur Ahuja
India

Homepage : http://madhur.netfirms.com
Email : madhur<underscore>ahuja<at>yahoo<dot>com
 
A

Andrew Thompson

The code that am using is:

No it is *not* the code you are using!

The code you provided does not compile.

But before you post your *actual* code, I suggest you
join all the try's in a single block and..
////////////////////////////
import java.io.*;
public class serial6 ....
catch( IOException e)
{
e.printStackTrace();

}

Exceptions (at least the stack traces) are your friend..
<http://www.physci.org/codes/javafaq.jsp#exact>

HTH

--
Andrew Thompson
http://www.PhySci.org/codes/ Web & IT Help
http://www.PhySci.org/ Open-source software suite
http://www.1point1C.org/ Science & Technology
http://www.lensescapes.com/ Images that escape the mundane
 
P

Paul Lutus

Madhur said:
Hello

I have been given the task of doing simple file handling in java.
i.e. I want to write set of records to a file and read them.
The problem is that writeObject function produces inconsistent
results when we write a series of records in one session and when
we write same number of records by running the program again and again
i.e. appending.

I recommend that you solve this and a dozen other problems by writing and
reading text, not objects. This suggestion may seen orthogonal to the
immediate problem you face, but in fact it *is* the problem you face.

Data records that are expected to have a lifetime longer than 15 minutes
should be written out in a way that they can be read successfully by a
different program running on a different platform. This ironically makes it
easier to read them with the originating program also.

And finally, if you write using a plain-text format, appending records to an
existing database is made much easier.
 
M

Michael Borgwardt

Madhur said:
I have been given the task of doing simple file handling in java.
i.e. I want to write set of records to a file and read them.
The problem is that writeObject function produces inconsistent
results when we write a series of records in one session and when
we write same number of records by running the program again and again
i.e. appending.
The file size differs in above 2 cases.

Thus reading the records produces this exception:
StreamCorruptedException

This exception occurs only when we read from the file in which data
has been appended.
The exception doesnt occurs if we write to file only once and then read.

That's because ObjectOutputStream doesn't just "write objects", it first
writes a header, and ObjectInputStream doesn't like encountering that
header in the middle of its input.

In think Paul is overstating the case, but you should be aware that
you will run into problems reading the serialized data when you
change the definitions of the classes you've serialized.

Anyway, in order to get this appending to work, you'd have to use
separate ObjectInputStreams for each "segment" (i.e. each part of
the file that was written by a separate ObjectOutputStream).
This can be done be prepending each of these segments with an
integer containing the number of "records" to read, or by ending
each segment with a special object that tells you that you now
have to use a new ObjectInputStream.
 
M

Madhur Ahuja

Andrew Thompson said:
No it is *not* the code you are using!

The code you provided does not compile.

But before you post your *actual* code, I suggest you
join all the try's in a single block and..


Exceptions (at least the stack traces) are your friend..
<http://www.physci.org/codes/javafaq.jsp#exact>

HTH


OK, I'll post the complete code. I trimmed the code for you
so that you may be able to easily grasp what is done in the code.
Here are the 2 files : serial6.java(writer) and serial4.java(reader)
///////////////////serial6.java///////////////
import java.io.*;

public class serial6
{
FileOutputStream fos = null;
FileInputStream fis = null;
ObjectOutputStream oos = null;
File ff;
public serial6()
{
try
{
MyClass1 obj1 = new MyClass1("sasas",12);
MyClass1 obj2 = new MyClass1("d",12);
try
{
ff=new File("serial133.txt");
if(ff.isFile())
{
System.out.println("exists");
}
else
{
System.out.println("not exists");
}

fis = new FileInputStream("serial133.txt");
fis.close();
fos = new FileOutputStream("serial133.txt",true);
System.out.println("not exists");



}
catch(FileNotFoundException e)
{
fos = new FileOutputStream("serial133.txt");

}



oos = new ObjectOutputStream(fos);
oos.writeObject(obj1);
// oos.writeObject(obj1);



} catch( IOException e)
{
}

try
{
oos.close();
} catch(IOException e) {

}
}

public serial6(int i)
{
try
{

FileOutputStream fos1 = new FileOutputStream("serial33.txt",true);
} catch(IOException e) {
}
}
public static void main(String args[])


serial6 sr = new serial6(1);
int ch =1;

// while(true)
{
switch(ch)
{
case 1:
serial6 sr1 = new serial6();

}
}
}
}

// import java.io.*;

class MyClass1 extends Object implements Serializable
{

String name;
int roll;
MyClass1(String a,int b)
{
this.name=a;
this.roll=b;

}
}
/////////////serial4.java///////////////////////
import java.io.*;

public class serial4
{
public static void main(String args[])
{
FileInputStream fis = null;
ObjectInputStream ois = null;
MyClass1 obj2 =null;
try


fis = new FileInputStream("serial233.txt");
ois = new ObjectInputStream(new BufferedInputStream(fis));


obj2 = (MyClass1)ois.readObject();

System.out.println(obj2.toString());

obj2 = (MyClass1)ois.readObject();

System.out.println(obj2.toString());


} catch(ClassNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);

} catch(EOFException e) {

System.out.println("Eof reached");
System.exit(1);
} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}

try
{
ois.close();
fis.close();

}catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
}
 
M

Madhur Ahuja

Michael Borgwardt said:
That's because ObjectOutputStream doesn't just "write objects", it
first writes a header, and ObjectInputStream doesn't like
encountering that header in the middle of its input.

Thanks, I didn't knew this.
In think Paul is overstating the case, but you should be aware that
you will run into problems reading the serialized data when you
change the definitions of the classes you've serialized.

Anyway, in order to get this appending to work, you'd have to use
separate ObjectInputStreams for each "segment" (i.e. each part of
the file that was written by a separate ObjectOutputStream).
This can be done be prepending each of these segments with an
integer containing the number of "records" to read, or by ending
each segment with a special object that tells you that you now
have to use a new ObjectInputStream.

Thanks for the suggestions. The first method(integers) looks nice.
But I am not able to understand second method. What could be that
special object , could it be for example an object with all zero fields.
So that when I read that object , and start a new ObjectInputStream whenever
I encounter object with null values.

I'll keep u updated about the improvement.
 
M

Mike Schilling

Michael Borgwardt said:
In think Paul is overstating the case, but you should be aware that
you will run into problems reading the serialized data when you
change the definitions of the classes you've serialized.

I agree with Paul. Object graph serialization and deserialization, is, like
synchronization, an area where Java makes a complex problem seem much
simpler than it is. Successfully persisting object graphs requires a level
of commitment to

understand how serialization works
design persistent classes sensibly
accept that persisting a class imposes large constraints on how that
class can evolve
plan for dealing with changes to persistent class definitions

Good Lord, how many times have we seen, right here on c.l.j.p, people
complaining that their files have gone corrupt, and by the way, they changed
their package names, that doesn't matter, does it?

Unless you're willing to really master the subject, stay away from
serializing objects into files. Just create data files, the old-fashioned
way.
 
A

Andrew Thompson

...
OK, I'll post the complete code. I trimmed the code for you
so that you may be able to easily grasp what is done in the code.

Is this a joke Madhur? Your second code
has compilation errors as well!

Try things like..
public static void main(String args[])


serial6 sr = new serial6(1);

If you need to pursue this further, please have
a close look over this document that describes
how to make examples for others..
<http://www.physci.org/codes/sscce.jsp>

--
Andrew Thompson
http://www.PhySci.org/codes/ Web & IT Help
http://www.PhySci.org/ Open-source software suite
http://www.1point1C.org/ Science & Technology
http://www.lensescapes.com/ Images that escape the mundane
 
M

Madhur Ahuja

Andrew Thompson said:
Is this a joke Madhur? Your second code
has compilation errors as well!

I can't believe it has. I simple copy pasted from the actual
source file. I even verified compiling it before posting.
Try things like..
public static void main(String args[])


serial6 sr = new serial6(1);

If you need to pursue this further, please have
a close look over this document that describes
how to make examples for others..
<http://www.physci.org/codes/sscce.jsp>

Anyway, I have solved the problem as indicated in other posts
and I'll take care in the future.
 
A

Andrew Thompson

I can't believe it has. I simple copy pasted from the actual
source file. I even verified compiling it before posting.

Look at the lines below, carefully.
They are directly quoted from your 2nd post.
public static void main(String args[])


serial6 sr = new serial6(1);

Where is the '{' after main()?

I cannot understand what you were doing,
but you seemed to be getting it wrong.

Your second class was also declared 'public'
which is something the link I referred you to
specifically advises not to do.
..I'll take care in the future.

Please do. The second post you made was
effectively 198 lines of wasted bandwidth.

--
Andrew Thompson
http://www.PhySci.org/codes/ Web & IT Help
http://www.PhySci.org/ Open-source software suite
http://www.1point1C.org/ Science & Technology
http://www.lensescapes.com/ Images that escape the mundane
 
M

Michael Borgwardt

Madhur said:
Thanks for the suggestions. The first method(integers) looks nice.
But I am not able to understand second method. What could be that
special object , could it be for example an object with all zero fields.
So that when I read that object , and start a new ObjectInputStream whenever
I encounter object with null values.

It doesn't really matter how you do it exactly, you just have to be able
to clearly identify such an object. Personally, i'd use a private inner
class with no members for that purpose and test for it with instanceof.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top