Java/File Input Output/PipedInputStream
Defines utility routines that use Java serialization
/*
* Copyright (c) 2004 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 3nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose,
* including teaching and use in open-source projects.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book,
* please visit http://www.davidflanagan.ru/javaexamples3.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
/**
* This class defines utility routines that use Java serialization.
*/
public class Serializer {
/**
* Serialize the object o (and any Serializable objects it refers to) and
* store its serialized state in File f.
*/
static void store(Serializable o, File f) throws IOException {
ObjectOutputStream out = // The class for serialization
new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(o); // This method serializes an object graph
out.close();
}
/**
* Deserialize the contents of File f and return the resulting object
*/
static Object load(File f) throws IOException, ClassNotFoundException {
ObjectInputStream in = // The class for de-serialization
new ObjectInputStream(new FileInputStream(f));
return in.readObject(); // This method deserializes an object graph
}
/**
* Use object serialization to make a "deep clone" of the object o. This
* method serializes o and all objects it refers to, and then deserializes
* that graph of objects, which means that everything is copied. This differs
* from the clone() method of an object which is usually implemented to
* produce a "shallow" clone that copies references to other objects, instead
* of copying all referenced objects.
*/
static Object deepclone(final Serializable o) throws IOException, ClassNotFoundException {
// Create a connected pair of "piped" streams.
// We"ll write bytes to one, and them from the other one.
final PipedOutputStream pipeout = new PipedOutputStream();
PipedInputStream pipein = new PipedInputStream(pipeout);
// Now define an independent thread to serialize the object and write
// its bytes to the PipedOutputStream
Thread writer = new Thread() {
public void run() {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(pipeout);
out.writeObject(o);
} catch (IOException e) {
} finally {
try {
out.close();
} catch (Exception e) {
}
}
}
};
writer.start(); // Make the thread start serializing and writing
// Meanwhile, in this thread, read and deserialize from the piped
// input stream. The resulting object is a deep clone of the original.
ObjectInputStream in = new ObjectInputStream(pipein);
return in.readObject();
}
/**
* This is a simple serializable data structure that we use below for testing
* the methods above
*/
public static class DataStructure implements Serializable {
String message;
int[] data;
DataStructure other;
public String toString() {
String s = message;
for (int i = 0; i < data.length; i++)
s += " " + data[i];
if (other != null)
s += "\n\t" + other.toString();
return s;
}
}
/** This class defines a main() method for testing */
public static class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// Create a simple object graph
DataStructure ds = new DataStructure();
ds.message = "hello world";
ds.data = new int[] { 1, 2, 3, 4 };
ds.other = new DataStructure();
ds.other.message = "nested structure";
ds.other.data = new int[] { 9, 8, 7 };
// Display the original object graph
System.out.println("Original data structure: " + ds);
// Output it to a file
File f = new File("datastructure.ser");
System.out.println("Storing to a file...");
Serializer.store(ds, f);
// Read it back from the file, and display it again
ds = (DataStructure) Serializer.load(f);
System.out.println("Read from the file: " + ds);
// Create a deep clone and display that. After making the copy
// modify the original to prove that the clone is "deep".
DataStructure ds2 = (DataStructure) Serializer.deepclone(ds);
ds.other.message = null;
ds.other.data = null; // Change original
System.out.println("Deep clone: " + ds2);
}
}
}
Test PipedInputStream and PipedOutputStream with Thread
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class TestPipes {
public static void writeData(OutputStream os) {
try {
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(os));
int[] numArray = { 1, 2, 3, 4, 5 };
for (int i = 0; i < numArray.length; i++) {
out.writeInt(numArray[i]);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readData(InputStream is) {
DataInputStream in = new DataInputStream(new BufferedInputStream(is));
boolean eof = false;
try {
while (!eof) {
int iValue = in.readInt();
System.out.println("read value = " + iValue);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("End of Data");
}
public static void main(String[] args) throws Exception {
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);
Runnable runOutput = new Runnable() {
public void run() {
writeData(pos);
}
};
Thread outThread = new Thread(runOutput, "outThread");
outThread.start();
Runnable runInput = new Runnable() {
public void run() {
readData(pis);
}
};
Thread inThread = new Thread(runInput, "inThread");
inThread.start();
}
}