字节流的高级应用
? 管道流
管道用来把一个程序、线程和代码块的输出连接到另一个程序、线程和代码块的输入。java.io中提供了类PipedInputStream和PipedOutputStream作为管道的输入/输出流
管道输入流作为一个通信管道的接收端,管道输出流则作为发送端。管道流必须是输入输出并用,即在使用管道前,两者必须进行连接
管道输入/输出流可以用两种方式进行连接:
– 在构造方法中进行连接
? PipedInputStream(PipedOutputStream pos);
? PipedOutputStream(PipedInputStream pis);
– 通过各自的connect()方法连接
? 在类PipedInputStream中,connect(PipedOutputStream pos);
? 在类PipedOutputStream中,connect(PipedInputStream pis);
PipedStream示例:
1.新建工程pipedstreamtest,在工程中建Sender.java,Receiver.java,PipedStreamTest.java文件
2.各Java文件代码如下:
2.1 Sender.java
package pipedstreamtest;
import java.io.*;
public class Sender extends Thread {
private PipedOutputStream out=new PipedOutputStream();
public PipedOutputStream getOutputStream(){
return out;
}
public Sender() {
}
public void run(){
String strInfo=new String("hello,receiver!");
try{
out.write(strInfo.getBytes());
out.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
2.2 Receiver.java
package pipedstreamtest;
import java.io.*;
public class Receiver extends Thread {
private PipedInputStream in=new PipedInputStream();
public PipedInputStream getInputStream(){
return in;
}
public void run(){
String strInfo=new String("hello,receiver!");
byte [] buf=new byte[1024];
try{
int len =in.read(buf);
System.out.println("the following message for sender:/n"+
new String(buf,0,len));
in.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public Receiver() {
}
}
2.3 PipedStream.java
package pipedstreamtest;
import java.io.*;
public class PipedStreamTest {
public static void main(String[] args) throws Exception{
Sender t1=new Sender();
Receiver t2=new Receiver();
PipedOutputStream out=t1.getOutputStream();
PipedInputStream in=t2.getInputStream();
out.connect(in);
t1.start();
t2.start();
}
}
例 8.8 管道流。
本例例管道流的使用方法。设输入管道in与输出管道out已连接,Send线程向输出管道out发送数据,Receive线程从输入管道in中接收数据。程序如下:
import java.io.*;
public class Pipedstream
{
public static void main (String args[])
{
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
try
{
in.connect(out);
}
catch(IOException ioe) { }
Send s1 = new Send(out,1);
Send s2 = new Send(out,2);
Receive r1 = new Receive(in);
Receive r2 = new Receive(in);
s1.start();
s2.start();
r1.start();
r2.start();
}
}
class Send extends Thread //发送线程
{
PipedOutputStream out;
static int count=0; //记录线程个数
int k=0;
public Send(PipedOutputStream out,int k)
{
this.out= out;
this.k= k;
this.count++; //线程个数加1
}
public void run( )
{
System.out.print("/r/nSend"+this.k+": "+this.getName()+" ");
int i=k;
try
{
while (i<10)
{
out.write(i);
i+=2;
sleep(1);
}
if (Send.count==1) //只剩一个线程时
{
out.close(); //关闭输入管道流
System.out.println(" out closed!");
}
else
this.count--; //线程个数减1
}
catch(InterruptedException e) { }
catch(IOException e) { }
}
}
class Receive extends Thread //接收线程
{
PipedInputStream in;
public Receive(PipedInputStream in)
{
this.in = in;
}
public void run( )
{
System.out.print("/r/nReceive: "+this.getName()+" ");
try
{
int i = in.read();
while (i!=-1) //输入流未结束时
{
System.out.print(i+" ");
i = in.read();
sleep(1);
}
in.close(); //关闭输入管道流
}
catch(InterruptedException e) { }
catch(IOException e)
{
System.out.println(e);
}
}
}
程序运行结果如下:
Send1: Thread-0
Send2: Thread-1
Receive: Thread-2 1
Receive: Thread-3 2 3 4 5 7 out closed!
6 8 9 java.io.IOException: Pipe closed!
? 数据流
DataInputStream和DataOutputStream
? 在提供了字节流的读写手段的同时,
? 以统一的通用的形式向输入流中写入boolean,int,long,double等基本数据类型,并可以在次把基本数据类型的值读取回来。
? 提供了字符串读写的手段。
? 分别实现了DataInput和DataOutput接口
声明类:
Public class DataInputStream extends filterInputStream implements DataInput
例 8.9 数据流。
本例演示数据流的使用方法。
程序如下:
import java.io.*;
public class Datastream
{
public static void main(String arg[])
{
String fname = "student1.dat";
new Student1("Wang").save(fname);
new Student1("Li").save(fname);
Student1.display(fname);
}
}
class Student1
{
static int count=0;
int number=1;
String name;
Student1(String n1)
{
this.count++; //编号自动加1
this.number = this.count;
this.name = n1;
}
Student1()
{
this("");
}
void save(String fname)
{
try
{ //添加方式创建文件输出流
FileOutputStream fout = new FileOutputStream(fname,true);
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(this.number);
dout.writeChars(this.name+"/n");
dout.close();
}
catch (IOException ioe){}
}
static void display(String fname)
{
try
{
FileInputStream fin = new FileInputStream(fname);
DataInputStream din = new DataInputStream(fin);
int i = din.readInt();
while (i!=-1) //输入流未结束时
{
System.out.print(i+" ");
char ch ;
while ((ch=din.readChar())!='/n') //字符串未结束时
System.out.print(ch);
System.out.println();
i = din.readInt();
}
din.close();
}
catch (IOException ioe){}
}
}
程序运行结果如下:
1 Wang
2 Li
? 对象流
? 对象的持续性(Persistence)
– 能够纪录自己的状态一边将来再生的能力,叫对象的持续性
? 对象的串行化(Serialization)
– 对象通过写出描述自己状态的的数值来记录自己的过程叫串行化。串行化的主要任务是写出对象实例变量的数值,如果变量是另一个对象的引用,则引用的对象也要串行化。这个过程是递归的
? 对象流
– 能够输入输出对象的流称为对象流。
– 可以将对象串行化后通过对象输入输出流写入文件或传送到其它地方
在java中,允许可串行化的对象在通过对象流进行传输。只有实现Serializable接口的类才能被串行化, Serializable接口中没有任何方法,当一个类声明实现Serializable接口时,只是表明该类加入对象串行化协议
要串行化一个对象,必须与一定的对象输出/输入流联系起来,通过对象输出流将对象状态保存下来(将对象保存到文件中,或者通过网络传送到其他地方) ,再通过对象输入流将对象状态恢复
类ObjectOutputStream和ObjectInputStream分别继承了接口ObjectOutput和ObjectInput,将数据 流功能扩展到可以读写对象,前者用writeObject()方法可以直接将对象保存到输出流中,而后者用readObject()方法可以直接从输入流 中读取一个对象
例 8.10 对象流。
本例声明Student2为序列化的类。Save方法中,创建对象输出流out,并以添加方式向文件中直接写入当前对象 out.writeObject(this);display方法中,创建对象输入流in,从文件中直接读取一个对象in.readObject(),获 得该对象的类名、接口名等属性,并显示其中的成员变量。程序如下:
import java.io.*;
public class Student2 implements Serializable //序列化
{
int number=1;
String name;
Student2(int number,String n1)
{
this.number = number;
this.name = n1;
}
Student2()
{
this(0,"");
}
void save(String fname)
{
try
{
FileOutputStream fout = new FileOutputStream(fname);
ObjectOutputStream out = new ObjectOutputStream(fout);
out.writeObject(this); //写入对象
out.close();
}
catch (FileNotFoundException fe){}
catch (IOException ioe){}
}
void display(String fname)
{
try
{
FileInputStream fin = new FileInputStream(fname);
ObjectInputStream in = new ObjectInputStream(fin);
Student2 u1 = (Student2)in.readObject(); //读取对象
System.out.println(u1.getClass().getName()+" "+
u1.getClass().getInterfaces()[0]);
System.out.println(" "+u1.number+" "+u1.name);
in.close();
}
catch (FileNotFoundException fe){}
catch (IOException ioe){}
catch (ClassNotFoundException ioe) {}
}
public static void main(String arg[])
{
String fname = "student2.obj";
Student2 s1 = new Student2(1,"Wang");
s1.save(fname);
s1.display(fname);
}
}
程序运行结果如下:
Student2 interface java.io.Serializable
1 Wang
From: http://hi.baidu.com/%C3%CE%C0%EF%CF%E3%B0%CD%C0%AD/blog/item/f442d803331071ee09fa9351.html