Date post: | 26-Dec-2015 |
Category: |
Documents |
Upload: | willa-newton |
View: | 242 times |
Download: | 1 times |
2
Stream= I/O abstraction-for any source (input) or sink (output) of data-hiding data handling in I/O device
Java 1.0
Java 1.1
Input Output
Java 1.0 and 1.1 I/O systems not separate designsBoth systems are used in parallel
InputStream OutputStream
Reader Writer
3
InputStream
“Physical” source
1. Byte array (memory)2. String object (memory)3. File4. Pipe (for interprocess/inter thread communication)5. Sequence of streams6. Others (e.g. internet connection – sockets)
InputStream
Application
4
InputStream
1. Byte array (memory)2. String object (memory)3. File4. Pipe (for interprocess/inter thread communication)5. Sequence of streams6. Others (e.g. internet connection – sockets)
InputStream
StringBufferInputStream
FileInputStream
PipedInputStream
SequenceInputStream
ByteArrayInputStream
InputStream has poor interfaceUsually wrapped in FilterInputStream-object !
5
FilterInputStream
1. DataInputStream - read primitive types (readXXX())2. BufferedInputStream - add buffering to InputStream3. LineNumberInputStream - add line numbers to InputStream4. PushbackInputStream - add push back buffer to InputStream5. InflaterInputStream - decompress InputStream
Inherits from InputStream !
All FilterInputStreams are decorators- ADD functionality, keep same interface- can be “concatenated”
e.g. InputStream in + line numbers and reading primitives :DataInputStream d=new DataInputStream(new LineNumberInputStream(in));
6
Java1.0 Input classes
Adaptation to physical devices
InputStream
StringBufferInputStream
FileInputStream
PipedInputStream
SequenceInputStream
ByteArrayInputStream FilterInputStream
DataInputStream
BufferedInputStream
LineNumberInputStream
PushbackInputStream
Decorators
InflaterInputStream
7
OutputStream
“Physical” destination
1. Byte array (memory)2. File3. Pipe (for interprocess/inter thread communication)4. Others (e.g. internet connection – sockets)
OutputStream
Application
8
OutputStream
1. Byte array (memory)2. File3. Pipe (for interprocess/inter thread communication)4. Others (e.g. internet connection – sockets)
OutputStream
FileOutputStream
PipedOutputStream
ByteArrayOutputStream
OutputStream has poor interfaceUsually wrapped in FilterOutputStream-object !
9
FilterOutputStream
1. DataOutputStream - write primitive types (writeXXX()) (binary format – use with DataInputStream)
2. BufferedOutputStream - add buffering to OutputStream3. PrintStream - add formatting to OutputStream
(text format – for “display” human readable output)4. DeflaterOutputStream - add compression to OutputStream
Inherits from OutputStream !
Decorator pattern is used (again)
e.g. OutputStream out + buffering + primitives
DataOutputStream d = new DataOutputStream(new BufferedOutputStream(out));
10
Java1.0 Output classes
Adaptation to physical devices
OutputStream
FileOutputStream
PipedOutputStream
ByteArrayOutputStream FilterOutputStream
DataOutputStream
BufferedOutputStream
PrintStream
Decorators
DeflaterOutputStream
11
A simple examplePrimitive output
import java.io.*;
import java.util.*;
class PrimitiveIO {
public static void main(String[] args) {
int[] a={1,3,5,7};
try {
writeInt(a,"Test.dat");
int[] b=readInt("Test.dat");
for(int i=0;i<b.length;i++)
System.out.print("- "+b[i]);
} catch(IOException e) {
e.printStackTrace();
}
}
public static void writeInt(int[] a,String n) throws IOException {
DataOutputStream o=new DataOutputStream(new FileOutputStream(n));
for(int i=0;i<a.length;i++)
o.writeInt(a[i]);
o.close();
}
// .. Continued …
}
12
A simple examplePrimitive input
class PrimitiveIO {
// … continued …
public static int[] readInt(String n) throws IOException {
int[] res;
ArrayList l=new ArrayList();
DataInputStream in=new DataInputStream(new BufferedInputStream(new FileInputStream(n)));
try {
while(true) l.add(new Integer(in.readInt()));
} catch(EOFException e) {
System.out.println("End of file reached !");
} finally {
in.close();
}
res=new int[l.size()];
for(int i=0;i<l.size();i++) res[i]=((Integer)(l.get(i))).intValue();
return res;
}
}
13
Java1.1Main changes/additions
• InputStream/OutputStream -> byte oriented (“pure binary”) new classes Reader/Writer -> char oriented (internationalization)
• support for object serialization
• provide bridges between Java1.0 and Java1.1 classes• class for random access files
Class hierarchy structure
InputStream ReaderInputStreamReader
ObjectInputStream
Java1.1 classes
14
Java1.1 : Reader
Adaptation
InputStream
StringBufferInputStream
FileInputStream
PipedInputStream
SequenceInputStream
ByteArrayInputStream
FilterInputStream
Decorators
DataInputStream
BufferedInputStream
LineNumberInputStream
PushbackInputStream
Adaptation
Reader
StringReader
FileReader
PipedReader
CharArrayReaderFilterReader
Decorators
BufferedReader
LineNumberReader
PushbackReader
InputStreamReaderObjectInputStream
byte oriented char oriented
InflaterInputStream
15
Java1.1 : Writer
Adaptation
OutputStream
Decorators
ByteArrayOutputStream
FileOutputStream
PipedOutputStreamDataOutputStream
BufferedOutputStream
PrintStream
Adaptation
Writer
OutputStreamWriter
Decorators
CharArrayWriter
FileWriterPipedWriter
BufferedWriter
PrintWriter
StringWriter
FilterWriter
ObjectOutputStream
byte oriented char oriented
FilterOutputStream
DeflaterOutputStream
16
The Java IO system
OutputStream Writer
InputStream Reader
RandomAccessFile
adapt adapt
adapt adapt
decorate decorate
decorate decorate
bridge
bridge
• use char oriented classes when possible• use byte oriented classes when necessary
17
Compression
OutputStream
FilterOutputStream
DeflaterOutputStream
ZipOutputStream
GZIPOutputStream
CheckedOutputStream
InputStream
FilterInputStream
InflaterInputStream
ZipInputStream
GZIPInputStream
CheckedInputStream
18
Read text lines from file
class TextFileInput {
public static void main(String[] args) {
try {
System.out.println(readTextFile("lines.txt"));
} catch(IOException e) {
System.err.println("IO Error !");
}
}
public static String readTextFile(String n) throws IOException {
BufferedReader in=new BufferedReader(new FileReader(n));
String s,res="";
while((s=in.readLine())!=null) res+=s+"\n";
in.close();
return res;
}
} Use standard conversion methods to read primitives from text file :
Integer.parseInt(s);
Double.parseDouble(s);
…
19
Read text lines from terminalimport java.io.*;
class TextTerminalInput {
public static void main(String[] args) {
try {
System.out.println(readTextTerminal());
} catch(IOException e) {
System.err.println("IO Error !");
}
}
public static String readTextTerminal() throws IOException {
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String s,res="";
System.out.print("Input text line : ");
while(!(s=in.readLine()).equals("")) {
res+=s+"\n";
System.out.print("Input text line : ");
}
return res;
}
}
InputStream
20
Write text to fileclass TextFileOutput {
public static void main(String[] args) {
String[] t={"First line","Second line","Third line"};
try {
writeTextFile("line.txt",t);
} catch(IOException e) {
System.err.println("IO Error !");
}
}
public static void writeTextFile(String n,String[] s) throws IOException {
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(n)));
for(int i=0;i<s.length;i++)
out.println(s[i]);
out.flush(); // flush buffer
out.close(); // close file
}
}
21
Standard device redirectionclass RedirectOutput{
public static void main(String[] args) {
try {
System.setOut(new PrintStream(
new BufferedOutputStream(new FileOutputStream(args[1]))));
System.out.println(readTextFile(args[0]));
System.out.close();
} catch(IOException e) {
System.err.println("IO Error ! "+e);
}
}
// same as for reading text from file
public static String readTextFile(String n) throws IOException {
BufferedReader in=new BufferedReader(new FileReader(n));
String s,res="";
while((s=in.readLine())!=null) res+=s+"\n";
in.close();
return res;
}
}
System.setIn(InputStream)System.setOut(PrintStream)System.setErr(PrintStream)
22
Read text from memoryclass MemoryInput {
public static void main(String[] args) {
String mem="Read from memory !";
try {
StringReader s=new StringReader(mem);
int c;
while((c=s.read())!=-1) System.out.print((char)c);
} catch(IOException e) {
System.err.println("Error in StringReader.");
}
byte[] b=mem.getBytes();
DataInputStream in=new DataInputStream(new ByteArrayInputStream(b));
System.out.println("");
try {
while(in.available()!=0) System.out.print((char)in.readByte());
} catch(IOException e) {
System.err.println("Error in ByteArrayInputStream.");
}
}
}
Memory buffer : byte[ ]
Remaining number of bytes
23
Write binary to file
class BinaryFileOutput {
public static void main(String[] args) {
try {
DataOutputStream out=new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("data.txt")));
out.writeFloat(3.14f);
out.writeDouble(3.1415926);
out.writeChar('t');
out.writeChars("Some text");
out.close();
} catch(IOException e) {
System.err.println("IO Error !");
}
}
}
24
Read binary from file
class BinaryFileInput {
public static void main(String[] args) {
try {
DataInputStream in=new DataInputStream(
new BufferedInputStream(new FileInputStream("data.txt")));
System.out.println(in.readFloat());
System.out.println(in.readDouble());
System.out.println(in.readLine()); // deprecated API !
in.close();
} catch(IOException e) {
System.err.println("IO Error !");
}
}
}3.143.1415926 t S o m e t e x t
25
Random access files
• unrelated to InputStream, OutputStream, Reader, Writer• constructor :
-file name-file mode : r [read only]
rw [read and write]• file pointer = index relative to file start (measured in bytes)
can be retrieved by : long getFilePointer()moved by : void seek(long)
• standard methods to read/writereadXXX : read primitive typewriteXXX : write primitive typereadUTF / write UTF : read/write StringreadLine : read String (line)read[Fully] / write[Fully] : read/write byte array
26
Random access files
class RandomAccess {
public static void main(String[] args) throws IOException {
RandomAccessFile r=new RandomAccessFile("random.dat","rw");
for(int i=0;i<10;i++) r.writeDouble(i*1.111);
for(int i=0;i<10;i+=2) {
r.seek(i*8); // 8 bytes for 1 double
r.writeDouble(i*1.1111);
}
// r.seek(10);
// r.writeInt(8);
r.seek(0);
while(r.getFilePointer()<r.length()) {
System.out.println(r.readDouble());
}
r.close();
}
}
0.0
1.0625000001265434
2.2222
3.333
4.4444
5.555
6.6666
7.777
8.8888
9.999
without //
0.0
1.111
2.2222
3.333
4.4444
5.555
6.6666
7.777
8.8888
9.999
with //
27
Serialization
= transform object into “wire format” (= bit sequence)
• store entire object on file (portable binary format)=> object can live beyond program termination
“lightweight persistence”used for JavaBeans (Java component model)
• send object across network=> application spread over multiple nodesdistributed computingused for Remote Method Invocation
(Java implementation of distributed objects)
28
Standard serialization
• class implements Serializable interface• writing :
create ObjectOutputStream (out)call out.writeObject(<object>)
• reading :create ObjectInputStream (in)call in.readObject()cast to specific class (result is of type Object)BUT : class file must be reachable by virtual machine !
29
Standard serialization
class A implements Serializable {private int a=0;private double b=12.0;private String s="Some data";public A() {System.out.println(" A() called.");}public A(int ia,double ib,String is) {
a=ia;b=ib;s=is;}public void setA(int ia) {a=ia;}public void setB(double ib) {b=ib;}public void setS(String is) {s=is;}public String toString() {
return "-> a="+a+" b="+b+" s="+s;}
}
30
Standard serializationclass WriteObject {
public static void main(String[] args) {
ArrayList o;
try { writeObjects("obj.dat");
} catch(IOException e) {System.err.println("Output Error : "+e);
}
try { o=readObjects("obj.dat");
for(int i=0;i<o.size();i++) System.out.println(o.get(i)); // no casting needed for toString
} catch(IOException e) { System.err.println("Input Error : "+e);
} catch(ClassNotFoundException e) { System.err.println("Class Error : "+e);
}
}
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1,10.0,"First.");A o2=new A(2,20.0,"Second.");
out.writeObject(o1);out.writeObject(o2);out.close();
}
public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {
ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));
ArrayList l=new ArrayList();
try { while(true) l.add(in.readObject());
} catch(EOFException e) {System.err.println("End of file reached.");}
in.close();
return l;
}
}
End of file reached.-> a=1 b=10.0 s=First.-> a=2 b=20.0 s=Second.
NO CONSTRUCTGOR CALLS TO RESTORE OBJECT !
31
Standard serializationStaticsclass A implements Serializable {
// .. Only changes shown …
private static char c;
public static void setC(char ic) {c=ic;}
public String toString() {
return "-> a="+a+" b="+b+" s="+s+" c = "+c;
}
public static void serializeStaticState(ObjectOutputStream o) throws IOException {
System.out.println("serializeStaticState().");
o.writeChar(c);
}
public static void deserializeStaticState(ObjectInputStream i) throws IOException {
System.out.println("deserializaStaticState().");
c=i.readChar();
}
}
Statics not serialized !IF needed :
• add custom static methods to serialize/deserialize static state• provide explicit calls for serializing/deserializing static state
32
Standard serializationStatics
class WriteObject { // … only changes shown …
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1,10.0,"First.");A o2=new A(2,20.0,"Second.");
A.setC('a');
out.writeObject(o1);
out.writeObject(o2);
A.serializeStaticState(out);
A.setC('b');
out.close();
}
public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {
ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));
ArrayList l=new ArrayList();
l.add(in.readObject());
l.add(in.readObject());
A.deserializeStaticState(in);
in.close();
return l;
}
}
serializeStaticState().deserializaStaticState().-> a=1 b=0.0 s=First. c = a-> a=2 b=0.0 s=Second. c = a
33
Aggregating serializablesclass A implements Serializable {
private int a=0;
private double b=12.0;
private String s="Some data";
private B myB;
public A() {System.out.println(" A() called.");}
public A(int ia,double ib,String is,B aB) {
a=ia;b=ib;s=is;myB=aB;
}
public void setA(int ia) {a=ia;}
public void setB(double ib) {b=ib;}
public void setS(String is) {s=is;}
public String toString() {
return "-> a="+a+" b="+b+" s="+s+myB;
}
}
class B implements Serializable { // MUST BE SERIALIZABLE !
private int c=0;
public B() {System.out.println(" B() called.");}
public B(int i) {c=i;};
public void setC(int ic) {c=ic;};
public String toString() {
return "\t c="+c;
}
}
34
Aggregating serializables
// … rest the same …
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1,10.0,"First.",new B(100));
A o2=new A(2,20.0,"Second.",new B(200));
out.writeObject(o1);
out.writeObject(o2);
out.close();
}
// …
End of file reached.-> a=1 b=10.0 s=First. c=100-> a=2 b=20.0 s=Second. c=200
Serialization mechanism follows the “web of objects”
35
Transient fieldsDo not serialize some fields :• some objects can not be serialized (e.g. Thread objects)• not logical to store permanently (e.g. password field) Mark fields as “transient”
class A implements Serializable {
private int a=0;
private transient double b=12.0;
private String s="Some data";
private transient B myB; // B not necessarily Serializable !
public A() {System.out.println(" A() called.");}
public A(int ia,double ib,String is,B aB) {
a=ia;b=ib;s=is;myB=aB;
}
public void setA(int ia) {a=ia;}
public void setB(double ib) {b=ib;}
public void setS(String is) {s=is;}
public String toString() {
return "-> a="+a+" b="+b+" s="+s+myB;
}
}
End of file reached.
-> a=1 b=0.0 s=First.null
-> a=2 b=0.0 s=Second.null
37
Customized serializationclass A implements Externalizable {
private int a=0;
private double b=12.0;
private String s="Some data";
public A() {System.out.println(" A() called.");}
public A(int ia,double ib,String is) {a=ia;b=ib;s=is;}
public void setA(int ia) {a=ia;}
public void setB(double ib) {b=ib;}
public void setS(String is) {s=is;}
public String toString() {return "-> a="+a+" b="+b+" s="+s;}
public void writeExternal(ObjectOutput o) throws IOException{
System.out.println("writeExternal().");
// super.writeExternal(o);
o.writeInt(a);o.writeDouble(b);o.writeObject(s);
}
public void readExternal(ObjectInput i) throws IOException,ClassNotFoundException {
System.out.println("readExternal().");
// super.readExternal(i);
a=i.readInt();b=i.readDouble();s=(String)i.readObject();
}
}
writeExternal().writeExternal(). A() called.readExternal(). A() called.readExternal().End of file reached.-> a=1 b=10.0 s=First.-> a=2 b=20.0 s=Second.
default constructor called ! (must be reachable !)
38
“TRICKY” Customized serialization
Customized serialization WITHOUT implementing Externalizable• implement Serializable• ADD (NOT override !) following methods :
• private void writeObject(ObjectOutputStream o) throws IOException• private void readObject(ObjectInputStream i) throws IOException
• customization options :• full customization• variation on standard serialization : use default methods
• o.defaultWriteObject()• i.defaultReadObject()
• this type of design can NOT be achieved in standard JAVA !
39
“TRICKY” Customized serialization
class A implements Serializable {
private int a=0;
private transient double b=12.0;
private String s="Some data";
public A() {System.out.println(" A() called.");}
public A(int ia,double ib,String is) {
a=ia;b=ib;s=is;
}
public void setA(int ia) {a=ia;}
public void setB(double ib) {b=ib;}
public void setS(String is) {s=is;}
public String toString() {
return "-> a="+a+" b="+b+" s="+s;
}
private void writeObject(ObjectOutputStream o) throws IOException{
System.out.println("writeObject().");
o.defaultWriteObject();
o.writeDouble((b<15.0) ? 0.0 : 100.0);
}
private void readObject(ObjectInputStream i) throws IOException,ClassNotFoundException {
System.out.println("readObject().");
i.defaultReadObject();
b=i.readDouble();
}
}
writeObject().writeObject().readObject().readObject().End of file reached.-> a=1 b=0.0 s=First.-> a=2 b=100.0 s=Second.
40
Inheritanceclass A implements Serializable {
private int a=0;
public A() {System.out.println(" A() called.");}
public A(int ia) {a=ia;}
public void setA(int ia) {a=ia;}
public String toString() {return super.toString()+"-> a="+a;}
}
class B extends A {
private int b=0;
public B() {System.out.println(" B() called.");}
public B(int ia,int ib) {super(ia);b=ib;};
public void setB(int ib) {b=ib;};
public String toString() {return super.toString()+"\t b="+b;}
}
class Serial1 {
// methods main and readObjects same as before
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1);
B o2=new B(2,20);
System.out.println(o1);System.out.println(o2);
out.writeObject(o1);out.writeObject(o2);
out.close();
}
}
A@6b97fd-> a=1B@1c78e57-> a=2 b=20End of file reached.A@8814e9-> a=1B@1503a3-> a=2 b=20
• no constructor calls• objects retrieved, stored at different location
41
Inheritanceclass A {
// same as before
}
class B extends A implements Serializable {
// same as before
}
class Serial2 { // main and readObjects same as before
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
B o2=new B(2,20);
System.out.println(o2);
out.writeObject(o2);
out.close();
}
}
B@6b97fd-> a=2 b=20 A() called.End of file reached.B@a83b8a-> a=0 b=20
• No-arg constructor called for unserializable base object• Only serializable part stored to and retrieved from stream
42
Inheritanceclass A implements Externalizable {
// same as before +
public void writeExternal(ObjectOutput o) throws IOException {
System.out.println("A.writeExternal().");
o.writeInt(a);
}
public void readExternal(ObjectInput i) throws IOException {
System.out.println("A.writeExternal().");
a=i.readInt();
}
}
class B extends A {
// same as before +
public void writeExternal(ObjectOutput o) throws IOException {
System.out.println("B.writeExternal().");
super.writeExternal(o);
o.writeInt(b);
}
public void readExternal(ObjectInput i) throws IOException {
System.out.println("B.writeExternal().");
super.readExternal(i);
b=i.readInt();
}
}
43
Inheritanceclass Serial3 {
// main and readObjects same as before
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1);
B o2=new B(2,20);
System.out.println(o1);System.out.println(o2);
out.writeObject(o1);out.writeObject(o2);out.close();
}
}
A@1c78e57-> a=1B@5224ee-> a=2 b=20A.writeExternal().B.writeExternal().A.writeExternal(). A() called.A.writeExternal(). A() called. B() called.B.writeExternal().A.writeExternal().End of file reached.A@c21495-> a=1B@1d5550d-> a=2 b=20
• call super-methods to store/retrieve base object (especially if private members …) • retrieving Externalizables ALWAYS calls constructor !
44
Aggregationclass A implements Serializable {
// clone method added to A
public Object clone() {return new A(a);}
}
class Serial4 {
// main and readObjects unchanged
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
A o1=new A(1);
System.out.println(o1);
out.writeObject(o1);
// out.close();
// out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
o1.setA(10);
System.out.println(o1);
out.writeObject(o1);
A o2=(A)o1.clone();
System.out.println(o2);
out.writeObject(o2);
out.close();
}
}
A@192d342-> a=1
A@192d342-> a=10
A@87816d-> a=10
End of file reached.
A@a83b8a-> a=1
A@a83b8a-> a=1
A@dd20f6-> a=10
with //
A@192d342-> a=1
A@192d342-> a=10
A@87816d-> a=10
End of file reached.
A@a83b8a-> a=10
A@dd20f6-> a=10
without //
• Serialization (to same stream !) avoids unnecessary (and dangerous) duplicates• Updates are unsafe !
45
Aggregationclass A implements Serializable {
private int a=0;
private B b;
public A() {System.out.println(" A() called.");}
public A(int ia,B ib) {a=ia;b=ib;}
public void setA(int ia) {a=ia;}
public B getB() {return b;}
public String toString() {
return super.toString()+"-> a="+a+b;
}
public Object clone() {return new A(a,(B)b.clone());}
}
class B implements Serializable {
private int b=0;
public B() {System.out.println(" B() called.");}
public B(int ib) {b=ib;};
public void setB(int ib) {b=ib;};
public String toString() {
return "\t"+super.toString()+" b="+b;
}
public Object clone() {return new B(b);}
}
46
Aggregationclass Serial5 { // main and readObjects unchanged
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
B b1=new B(10);
B b2=new B(20);
A a1=new A(1,b1);
//A a2=new A(2,b2); //[1]
//A a2=new A(2,(B)b1.clone()); //[2]
A a2=new A(2,b1); //[3]
System.out.println(a1);
System.out.println(a2);
out.writeObject(a1);
out.writeObject(a2);
out.close();
}
}
A@6b97fd-> a=1 B@1c78e57 b=10
A@5224ee-> a=2 B@f6a746 b=20
End of file reached.
A@743399-> a=1 B@e7b241 b=10
A@167d940-> a=2 B@e83912 b=20wit
h [
1]
A@6b97fd-> a=1 B@1c78e57 b=10
A@5224ee-> a=2 B@f6a746 b=10
End of file reached.
A@743399-> a=1 B@e7b241 b=10
A@167d940-> a=2 B@e83912 b=10
Serialization maintains “web of object logic”
A@6b97fd-> a=1 B@1c78e57 b=10
A@5224ee-> a=2 B@1c78e57 b=10
End of file reached.
A@1a1c887-> a=1 B@743399 b=10
A@e7b241-> a=2 B@743399 b=10
wit
h [
2]
wit
h [
3]
47
Aggregation// main and readObjects unchanged
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
B b=new B(10);
A a1=new A(1,b);
A a2=new A(2,b);
System.out.println(a1);
out.writeObject(a1);
b.setB(100);
System.out.println(a2);
out.writeObject(a2);
out.close();
}
A@6b97fd-> a=1 B@1c78e57 b=10
A@dd20f6-> a=2 B@1c78e57 b=100
End of file reached.
A@1a1c887-> a=1 B@743399 b=10
A@e7b241-> a=2 B@743399 b=10
48
Aggregation// main unchanged
public static void writeObjects(String n) throws IOException {
ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));
B b=new B(10);
A a1=new A(1,b);
A a2=new A(2,b);
System.out.println(a1);
out.writeObject(a1);
System.out.println(a2);
out.writeObject(a2);
out.close();
}
public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {
ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));
ArrayList l=new ArrayList();
A a1=(A)in.readObject();
a1.getB().setB(100);
A a2=(A)in.readObject();
l.add(a1);
l.add(a2);
in.close();
return l;
}
A@192d342-> a=1 B@6b97fd b=10
A@a83b8a-> a=2 B@6b97fd b=10
A@1503a3-> a=1 B@1a1c887 b=100
A@743399-> a=2 B@1a1c887 b=100
49
Conclusion
3 options to serialize• implement Serializable (some customization possible using “transient”)• implement Externalizable (full customization necessary)• use trick with Serializable
Serialization is not identical to writing to standard stream• web of objects is maintained• changes to objects while stream is open : considered unsafe
Advice : consider serialization “Atomic”• collect all related objects in 1 collection• store/retrieve in 1 serialization operation