------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
对程序语言设计者来说,设计一个令人满意的I/O系统,是极其艰巨的一个任务。——《Think in java》
关于I/O系统的设计,话再多的时间去研究也不足为怪,这里仅仅我再初步学习I/O时的点点滴滴的记录。
一、File类
File类是File类是java.io包中唯一处理磁盘文件和目录的类。它提供的方法都是与平台无关的,
通过使用File类提供各种方法能够创建、删除文件和目录,或者获取磁盘上指定的文件和目录的相关信息。
package com.tai.io;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class FileDemo
{
/**
* File类是java.io包中唯一处理磁盘文件和目录的类。它提供的方法都是与平台无关的,
* 通过使用File类提供各种方法能够创建、删除文件和目录,或者获取磁盘上指定的文件和目录的相关信息。
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
File file = new File("E:/文件夹");
if(file.mkdir())
{
System.out.println("文件夹已创建!");
}
File file2 = new File("E:/文件夹/文件.txt");
if(file2.createNewFile())
{
System.out.println("文件已经创建!");
}
getInfor(file2);
if(file2.delete())
{
System.out.println("文件已删除!");
}
File Dir = new File("C:"+File.separator+"abc");//separator 文件分割符这样写便于代码跨平台,更加健壮!
fFilter(Dir);
}
/*
*获取相关信息
*/
private static void getInfor(File file)
{
System.out.println("文件名"+file.getName());
System.out.println("文件父路径"+file.getParent());
System.out.println("文件的绝对路径"+file.getAbsolutePath());
System.out.println("所在磁盘的大小"+file.getTotalSpace()/(1024*1024*1024)+"GB");
System.out.println("所在磁盘的可用空间"+file.getUsableSpace()/(1024*1024*1024)+"GB");
System.out.println("是否是文件"+file.isFile());
System.out.println("是否是文件夹"+file.isDirectory());
System.out.println("是否是隐藏文件"+file.isHidden());
System.out.println("是否可读"+file.canRead()+" 是否可写"+file.canWrite()+" 是否可执行"+file.canExecute());
}
/*
* FilenameFilter 过滤接口 此处用内部类实现FileFilter的accept()方法
* FilenameFilter和FileFilter类似,也提供文件过滤功能
* 性能上FilennameFilter较FileFilter效率稍高
*/
private static void fFilter(File file)
{
File[] files = file.listFiles(new FileFilter()
{
@Override
public boolean accept(File pathname)
{
if(pathname.isFile()&&pathname.getName().endsWith(".txt"))
{
return true;
}
return false;
}
});
System.out.println("该目录下的所有文本文件");
for(File f:files)
{
System.out.println(f.getName());
}
}
}
运行结果:
文件夹已创建!
文件已经创建!
文件名文件.txt
文件父路径E:\文件夹
文件的绝对路径E:\文件夹\文件.txt
所在磁盘的大小84GB
所在磁盘的可用空间31GB
是否是文件true
是否是文件夹false
是否是隐藏文件false
是否可读true 是否可写true 是否可执行true
文件已删除!
该目录下的所有文本文件
b.txt
新建文本文档 (2).txt
新建文本文档.txt
二、字节流
计算机中的数据都是以字节为单位进行处理的,这类的数据保存文件也成为“二进制文本”,在Java中对这些文本的操作就是要使用Java的字节流对象。
InputStream和OutputStream分别是输入与输出字节流,它们都是抽象类型的,都不能实例化,它们在I/O包中的顶层,作为了众多字节流的父类。
Java中的字节流有很多,这是我写的几个常用的字节流Demo.
FileInputStream/FileOutputStream
FileInputStream与FileOutputStream 被称为文件流,是最常见的字节流。用于对磁盘文件的读写操作。
* File类不只能创建、删除、获取文剪信息,但是不能打开和读写文件。FileInputStream与FileOutoutStream就是用于读写文件的
* FileInputStream 的构造方法
* FileInputStream fis = new FileInputStream("c:/abc");
File file = new File("c:/abc");
FileInputStream fis = new FileInputStream(file);
为了简化常用:
FileInputStream fis = new FileInputStream(new File("c:/abc"));
package com.tai.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo
{
/**
* FileInputStream与FileOutputStream 被称为文件流,是最常见的字节流。用于对磁盘文件的读写操作。
* File类不只能创建、删除、获取文剪信息,但是不能打开和读写文件。FileInputStream与FileOutoutStream就是用于读写文件的
* FileInputStream 的构造方法
* FileInputStream fis = new FileInputStream("c:/abc");
File file = new File("c:/abc");
FileInputStream fis = new FileInputStream(file);
为了简化常用:
FileInputStream fis = new FileInputStream(new File("c:/abc"));
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
FileInputStream fis = new FileInputStream(new File("C:/abc/Demo.txt"));
FileInputStream fis2 = new FileInputStream(new File("C:/abc/b.txt"));
int b=0,len=0;
System.out.println("使用read()方法,每次读一个字节:");
//使用循环,每次读入一个字节,直到文件结尾。
while((b=fis.read())!=-1)
{
System.out.print((char)b);
}
fis.close();
System.out.println("\n使用read(byte[] b)的方法,读取文件存入字符数组中");
//读取文件,直到结尾,存入byte数组中,打印。
byte[] bt = new byte[516];
while(-1!=(len=fis2.read(bt,0,516)))
{
String str = new String(bt,0,len);这里需要特别注意的是 从0到len len是实际的长度可能不到516 、
System.out.print(str);
}
fis2.close();
}
}
运行结果:
使用read()方法,每次读一个字节:
this is a FileInputDemo.
使用read(byte[] b)的方法,读取文件存入字符数组中
回家过年,这本是很简单的四个字,却是许许多多游子一年中的期盼,当然,这也包括那些在外求学的莘莘学子们。
在外瓢泼久了,多想回到家乡看看为我们牵挂的父母亲人。曾经多少个日日夜夜想及这些,我们可以做的只是一壶浊酒而后在心底默默的祝福与思念。
“举头望明月,低头思故乡”一年到头,隐藏在我们心底的除了深深的牵挂还剩下什么呢?一年到头,又有多少父母无时无刻不在思念着远方的儿女?
记得还小的时候我们是多么的喜欢过年,有新衣服穿、有压岁钱拿,好多好吃好玩的,还不用担心作业是否已经完成。而今我们盼望着过年,却只是那短暂的团聚,可以陪父母陪亲人说说心里的话。同时我们又多么地害怕,害怕父母那期望的眼神,尤其是害怕看见父母那满头乌发渐渐泛白,甚至脱落。虽然我知道,人没有不会老的,但看见父母脸上渐添的皱纹,和那渐渐泛白的乌发,心中总会有一种心酸的感觉。
FileOutputStream
* FileOutputStream类是用于向磁盘文件写入字符数据的输出类
* 当想磁盘某个文件写入时如果文件不存在它不会向FileInputStream那样抛异常,而是创建一个新的文件。
* 构造方法与FileInputStream类似,但是有的会多个参数:
* FileOutputStream fos = new FileOutputStream(File file,boolean append)
* append 是否想文件尾部追加 true 在该文件的结尾追加内容,flase将清除原有的内容,添加新的内容。
package com.tai.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo
{
/**
* 本程序的功能是将一个文本中的内容复制到另一个文本中。
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
FileInputStream fis = new FileInputStream(new File("C:/abc/Demo.txt"));
FileOutputStream fos = new FileOutputStream(new File("C:/abc/Demo2.txt"),false);
int b= 0,len=0;
byte[] bt = new byte[512];
while(-1!=(len=fis.read(bt,0,512) ) )
{
fos.write(bt,0,len);
}
System.out.println("已经吧Demo.txt中的内容复制到了Demo2.txt中!!");
fos.close();
fis.close();
FileOutputStream fos2 = new FileOutputStream(new File("C:/abc/Demo3.txt"),false);
writein(fos2,"hello world!");
System.out.println("已经hello world写入到了文件C:/abc/Demo3.txt中");
}
/*
* 简单的向文件写入字符串
*/
private static void writein(FileOutputStream fos,String str)
{
byte[] b = str.getBytes();
try
{
fos.write(b);
fos.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
已经吧Demo.txt中的内容复制到了Demo2.txt中!!
已经hello world写入到了文件C:/abc/Demo3.txt中
java.io包中提供了FilterInputStream和FilterOutputStream类分别对其他输入输出流进行特殊的处理,它们在
* 读/写数据的同时还能够对数据进行特殊的处理。另外它们还提供了同步机制,是的某一时刻之后一个线程可以访问输入/输出流。
* FilterInputStream/FilterOutputStream都是抽象类。
* FilterInputStream有三个子类:BufferedInputStream、DataInputStream、PushbackInputStream
* FilterOutputStream也有三个子类:BufferedOutputStream、DataOutoutStream、PrintStream
*
* 使用过滤字节流的时候,必须先制定节点流对象处理底层的数据,然后把节点流对象作为过滤流对象的实参使用。即把过滤流对象连接到某个输入/输出节点流对象上如下:
* FileInputStream fis = new FileInputStream(new File("c:/abc.txt"));
* DataInputSream dis = new DataInputStream(fis);
一、BufferedInputStream/BufferedOutputStream
* BufferedInputStream/BufferedOutputStream 是缓冲字节流,它引入了针对内存缓冲区的操作,从而提高了读写数据的效率。
* 缓冲区的默认大小为32字节,也可以指定缓冲区的大小。
* 相应的构造的方法
* BufferedInputStream(InputStream in) 这里的in只要是继承自InputSream的对象都可以作为参数
* BufferedInputStream(InputStream in,int size)
* BufferedOutputStream与上面的对应。
Demo:使用BufferedInputStream/BufferdeOutputStream完成文件的复制。
package com.tai.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedInputStreamDemo
{
/**
* java.io包中提供了FilterInputStream和FilterOutputStream类分别对其他输入输出流进行特殊的处理,它们在
* 读/写数据的同时还能够对数据进行特殊的处理。另外它们还提供了同步机制,是的某一时刻之后一个线程可以访问输入/输出流。
* FilterInputStream/FilterOutputStream都是抽象类。
* FilterInputStream有三个子类:BufferedInputStream、DataInputStream、PushbackInputStream
* FilterOutputStream也有三个子类:BufferedOutputStream、DataOutoutStream、PrintStream
*
* 使用过滤字节流的时候,必须先制定节点流对象处理底层的数据,然后把节点流对象作为过滤流对象的实参使用。即把过滤流对象连接到某个输入/输出节点流对象上
*
* FileInputStream fis = new FileInputStream(new File("c:/abc.txt"));
* DataInputSream dis = new DataInputStream(fis);
* BufferedInputStream/BufferedOutputStream 是缓冲字节流,它引入了针对内存缓冲区的操作,从而提高了读写数据的效率。
* 缓冲区的默认大小为32字节,也可以指定缓冲区的大小。
* 相应的构造的方法
* BufferedInputStream(InputStream in) 这里的in只要是继承自InputSream的对象都可以作为参数
* BufferedInputStream(InputStream in,int size)
* BufferedOutputStream与上面的对应。
*/
public static void main(String[] args) throws IOException
{
FileInputStream fis = new FileInputStream(new File("c:/曲婉婷 - 没有什么不同 [mqms].mp3"));
BufferedInputStream bis = new BufferedInputStream(fis,1024);
FileOutputStream fos = new FileOutputStream(new File("c:/没有什么不同.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
byte[] buffer = new byte[1024];
int len =0;
while(-1!=(len=bis.read(buffer,0,1024)))
{
//将buffer中从fis读取来的数据写入到bos中
bos.write(buffer,0,len);
}
bos.flush();//最近一次读取的数据可能达不到1024字节,这里强制清空缓冲区\
System.out.println("已经将c:/曲婉婷 - 没有什么不同 [mqms].mp3复制到c:/没有什么不同.mp3");
bos.close();
fos.close();
}
}
二、DataInputStream和DataOutputStream
* java.io包中还有连个接口DataInput和DataOutput,这两个接口设计了较高级的数据输入输出方式,除了可以处理字节个字节数组外
* 还可以处理 int、float、boolean等基本的数据类型,这些数据在文件中的表示方式和它们在内存中的方式一样,无序转换,它们相应的提供了
* 很多处理基本数据类型的方法,如:DataInput提供了read()、readInt()、readByte()等DataOutput提供了write()、writeInt()、
* writeFloat()、writeChar()等 ....
*
* 而数据流类 DataInputStream和DataOutputStream分别实现了DataInput和DataOutput接口。它们以统一的方式向输入流中写入boolean、int、long
* double等基本的数据类型,并且还可以把基本的数据类型取出来,同时它们也有针对字符串的读写方法
Demo:
package com.tai.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class DataInputStreamDemo
{
/**
* java.io包中还有连个接口DataInput和DataOutput,这两个接口设计了较高级的数据输入输出方式,除了可以处理字节个字节数组外
* 还可以处理 int、float、boolean等基本的数据类型,这些数据在文件中的表示方式和它们在内存中的方式一样,无序转换,它们相应的提供了
* 很多处理基本数据类型的方法,如:DataInput提供了read()、readInt()、readByte()等DataOutput提供了write()、writeInt()、
* writeFloat()、writeChar()等 ....
*
* 而数据流类 DataInputStream和DataOutputStream分别实现了DataInput和DataOutput接口。它们以统一的方式向输入流中写入boolean、int、long
* double等基本的数据类型,并且还可以把基本的数据类型取出来,同时它们也有针对字符串的读写方法
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
FileOutputStream fos = new FileOutputStream(new File("C:/abc/a.txt"));
DataOutputStream dos = new DataOutputStream(fos);
Scanner scan = new Scanner(System.in);
System.out.println("请输入数据: ");
dos.writeBoolean(scan.nextBoolean());
dos.writeByte(scan.nextInt());
dos.writeFloat(scan.nextFloat());
dos.writeShort(scan.nextInt());
dos.writeChar('A');
dos.close();
FileInputStream fis = new FileInputStream(new File("C:/abc/a.txt"));
DataInputStream dis = new DataInputStream(fis);
System.out.println("读取Boolean数据 \t" + dis.readBoolean());
System.out.println("读取Byte数据 \t" + dis.readByte());
System.out.println("读取Float数据 \t" + dis.readFloat());
System.out.println("读取Short数据 \t" + dis.readShort());
System.out.println("读取Char数据 \t" + dis.readChar());
dis.close();
}
}
管道字节流
* 管道用来把程序、线程或程序块的输出连接到另一个程序、线程或者程序块作为它的输入。
* java.io提供了类PipedInputSteramh和PipedOutputStream 作为管道的输入/输出流。
* 管道输入流作为一个通信管道接收端,管道输出流作为发送端。管道流必须是输入流输出流同时并用,即在使用管道前,两者必须进行连接。
* 无论PipedInputStream还是PipdeOutputStream类都提供了connect()方法可以使用connect()方法建立一个管道进行数据传输。
* 管道输入/输出流可以用两种方式进行连接,一种方式是使用connect()方法:
* PipedInputStream pis = new PipedInputStream();
* PipedOutputStream pos = new PipedOutputStream();
* pis.connect(pos);
* pos.connect(pis);
* 另外一种是直接使用构造方法进行连接:
* PipedInputStream pis = new PipedInputStream();
* PipedOutputStream pos = new PipedOutputStream(pis);
*
* 除了connect()方法PipedInputStream类还继承了InputStream类的read()方法。另外又增加了receive()方法
* PipedOutputStream类也继承自OutputStream类的write()方法。
Demo1:
package com.tai.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamDemo
{
/**
* 管道字节流
* 管道用来把程序、线程或程序块的输出连接到另一个程序、线程或者程序块作为它的输入。
* java.io提供了类PipedInputSteramh和PipedOutputStream 作为管道的输入/输出流。
* 管道输入流作为一个通信管道接收端,管道输出流作为发送端。管道流必须是输入流输出流同时并用,即在使用管道前,两者必须进行连接。
* 无论PipedInputStream还是PipdeOutputStream类都提供了connect()方法可以使用connect()方法建立一个管道进行数据传输。
* 管道输入/输出流可以用两种方式进行连接,一种方式是使用connect()方法:
* PipedInputStream pis = new PipedInputStream();
* PipedOutputStream pos = new PipedOutputStream();
* pis.connect(pos);
* pos.connect(pis);
* 另外一种是直接使用构造方法进行连接:
* PipedInputStream pis = new PipedInputStream();
* PipedOutputStream pos = new PipedOutputStream(pis);
*
* 除了connect()方法PipedInputStream类还继承了InputStream类的read()方法。另外又增加了receive()方法
* PipedOutputStream类也继承自OutputStream类的write()方法。
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
int ch1 = 0;
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
//也可以使用connect()方法
// PipedOutputStream pos = new PipedOutputStream();
// pos.connect(pis);
System.out.println("请输入一个字符,按#结束程序!");
while((ch1 = System.in.read())!='#')
{
pos.write(ch1);
System.out.println((char)pis.read());
}
}
}
PipedInputStream 和PipedOutStream常与线程连用,已达到在不同线程间的通讯:
package com.tai.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamDemo2
{
public static void main(String[] args) throws IOException
{
PipedInputStream pis = new PipedInputStream();
//实例管道输出流并与上面的管道输入流连接
PipedOutputStream pos = new PipedOutputStream(pis);
new Thread(new InputThread(pis)).start();
new Thread(new OutputThread(pos)).start();
}
}
class InputThread implements Runnable
{
private PipedInputStream pis;
public InputThread(PipedInputStream in)
{
this.pis = in;
}
@Override
public void run()
{
byte[] buffer = new byte[1024];
int len = 0;
try
{
len = pis.read(buffer);
String str = new String(buffer,0,len);
System.out.println("管道输入流作为接收端,接受来自管道输出流发送的内容。 内容是: "+ str);
pis.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class OutputThread implements Runnable
{
private PipedOutputStream pos;
public OutputThread (PipedOutputStream out)
{
this.pos = out;
}
@Override
public void run()
{
try
{
pos.write("管道输出流作为发送端向管道输入流发送内容".getBytes());
pos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
对象持久化(Persistence)就是 将对象保存到磁盘文件或者网络中,保存对象的过程实质上就是对象持久化的过程。
* 也就是记录对象的状态以便于将来具有再生的能力。 Java提供了对象流以实现对象的输入输出,也就是实现对象的持久化。
* 需要注意的是在使用对象流之前必须要将该对象序列化。所谓的序列化就是将对象的状态转化成字节流,并且以后可以通过这些值 再生成相同状态的对象。
* 简单来说序列化就是一种用来处理对象流的机制,而对象流也就是将对象的内容进行流化,我们可以对流化后的对象进行读取操作,
* 也可以将流化后的对象传输于网络之间。
*
* 对象序列化,只需要被序列化的类实现Serializable接口就可以了。
* Serializable接口中没有任何的方法,让一个类实现该接口只是为了标注该对象是可以被序列化的,然后就可以对该对象进行持久化。
*
* 注意: 序列化只能保存对象的实例变量,但不能保存类的任何方法和类变量,并且保存的只是变量的值。 对于任何修饰符都不能保存。
* 有些类型的变量是瞬时的,这样的对象也是无法保存的,如:线程对象、或流对象。对于这样的变量,必须用transient关键字标明,否则编译器将报错。
*
* 任何被transient标明的成员变量,将不被保存。
* 考虑到序列化可能涉及对象保存在磁盘上或者网络上,对于一些保密的数据就要加上transient关键字。
*
*
* 对象序列化之后,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象的状态保存下来,再通过对象输入流将对象的状态恢复。
* java提供了ObjectInputStream
* 类和ObjectOutputStream类分别实现了ObjectInput和ObjectOutput。
* ObjectOutput接口用writeObject
* ()方法,可以将对象的状态保存到输出流中。而ObjectInput接口用readObject()方法以从输入流中读入一个对象。
*
package com.tai.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class PersistenceDome
{
/**
* 对象持久化(Persistence)就是 将对象保存到磁盘文件或者网络中,保存对象的过程实质上就是对象持久化的过程。
* 也就是记录对象的状态以便于将来具有再生的能力。 Java提供了对象流以实现对象的输入输出,也就是实现对象的持久化。
* 需要注意的是在使用对象流之前必须要将该对象序列化。所谓的序列化就是将对象的状态转化成字节流,并且以后可以通过这些值 再生成相同状态的对象。
* 简单来说序列化就是一种用来处理对象流的机制,而对象流也就是将对象的内容进行流化,我们可以对流化后的对象进行读取操作,
* 也可以将流化后的对象传输于网络之间。
*
* 对象序列化,只需要被序列化的类实现Serializable接口就可以了。
* Serializable接口中没有任何的方法,让一个类实现该接口只是为了标注该对象是可以被序列化的,然后就可以对该对象进行持久化。
*
* 注意: 序列化只能保存对象的实例变量,但不能保存类的任何方法和类变量,并且保存的只是变量的值。 对于任何修饰符都不能保存。
* 有些类型的变量是瞬时的,这样的对象也是无法保存的,如:线程对象、或流对象。对于这样的变量,必须用transient关键字标明,否则编译器将报错。
*
* 任何被transient标明的成员变量,将不被保存。
* 考虑到序列化可能涉及对象保存在磁盘上或者网络上,对于一些保密的数据就要加上transient关键字。
*
*
* 对象序列化之后,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象的状态保存下来,再通过对象输入流将对象的状态恢复。
* java提供了ObjectInputStream
* 类和ObjectOutputStream类分别实现了ObjectInput和ObjectOutput。
* ObjectOutput接口用writeObject
* ()方法,可以将对象的状态保存到输出流中。而ObjectInput接口用readObject()方法以从输入流中读入一个对象。
*
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
Person p = new Person("张三", "Mauiie", "男");
Person p2 = new Person("p2", "Mauiie", "男");
Person p3 = new Person("p3", "Mauiie", "男");
Student s = new Student("孙俪", "Mauiie", "女");
Person temp = null;
Person temp2 = null;
Student stemp = null;
FileOutputStream fos = new FileOutputStream("c:/data.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
oos.writeObject(p2);
// oos.writeObject(p3);
oos.writeObject(s);
oos.close();
System.out.println("已经将p和s对象写入到了 c:/data.dat");
FileInputStream fis = new FileInputStream("c:/data.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
temp = (Person) ois.readObject();
temp2 = (Person) ois.readObject();
stemp = (Student) ois.readObject();
ois.close();
System.out.println(temp.toString());
System.out.println(stemp.toString());
System.out.println(temp2.toString());
}
}
class Person implements Serializable
{
String Pname;
transient String Pid;
String Psex;
public Person(String name, String ID, String sex)
{
this.Pname = name;
this.Pid = ID;
this.Psex = sex;
}
public String toString()
{
return "Name " + Pname + " ID " + Pid + " sex " + Psex;
}
}
class Student implements Serializable
{
String Sname;
transient String Sid;
String Ssex;
public Student(String name, String ID, String sex)
{
this.Sname = name;
this.Sid = ID;
this.Ssex = sex;
}
public String toString()
{
return "这是Student对象 " + "Name " + Sname + " ID " + Sid
+ " sex " + Ssex;
}
}
ObjectInputStream/ObjectOutputStream
运行结果:
已经将p和s对象写入到了 c:/data.dat
Name 张三 ID null sex 男
这是Student对象 Name 孙俪 ID null sex 女
Name p2 ID null sex 男
值得注意的是:
使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应。
ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头。因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头。
所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException。
一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法。被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object?
若是,则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法。