Java中的I/O操作
流式I/O
1) 流(Stream)是字节的源或目的。
2) 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。
流的分类
1) 节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
2) 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。
基本的流类
1) FileInputStream和FileOutputStream
节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。基本用法如下:
FileOutputStream fos=new FileOutputStream("1.txt");
fos.write("welcome to my blog!".getBytes());
fos.close();
FileInputStream fis=new FileInputStream("1.txt");
byte []buf=new byte[100];
int len=fis.read(buf);
System.out.println(new String(buf,0,len));
2) BufferedInputStream和BufferedOutputStream
过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。基本用法如下:
FileOutputStream fos=new FileOutputStream("1.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
bos.write("welcome to my blog!".getBytes());
bos.flush();
bos.close();
FileInputStream fis=new FileInputStream("1.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
byte[]buf=new byte[100];
int len=bis.read(buf);
System.out.println(new String(buf,0,len));
bis.close();
3) DataInputStream和DataOutputStream
过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
FileOutputStream fos=new FileOutputStream("1.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
DataOutputStream dos=new DataOutputStream(bos);
int i=10;
byte b=3;
char c='c';
float f=10.1f;
dos.writeInt(i);
dos.writeByte(b);
dos.writeChar(c);
dos.writeFloat(f);
dos.flush();
dos.close();
FileInputStream fis=new FileInputStream("1.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
DataInputStream dis=new DataInputStream(bis);
System.out.println(dis.readInt());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readFloat());
dis.close();
4) PipedInputStream和PipedOutputStream
管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。
PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream();
pos.connect(pis);
Reader和Writer
1) Java程序语言使用Unicode来表示字符串和字符。
2) Reader和Writer这两个抽象类主要用来读写字符流。
FileOutputStream fos=new FileOutputStream("1.txt");
OutputStreamWriter osw=new OutputStreamWriter(fos);
BufferedWriter bw=new BufferedWriter(osw);
bw.write("welcome to my blog!");
bw.close();
FileInputStream fis=new FileInputStream("1.txt");
InputStreamReader isr=new InputStreamReader(fis);
BufferedReader br=new BufferedReader(isr);
System.out.println(br.readLine());
br.close();
RandomAccessFile
1) RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类可以在文件的任何位置读取或写入数据。
2) RandomAccessFile类提供了一个文件指针,用来标志要进行读写操作的下一数据的位置。
对象序列化
1) 将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。
2) 将一个对象保存到永久存储设备上称为持续性。
3) 一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。
4) 当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
5) 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
6) 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。
import java.io.*;
class ObjectSerialTest
{
public static void main(String[]args)throws Exception
{
Student s1=new Student(1,"zhangshan",98.0);
Student s2=new Student(2,"lisi",93.0);
Student s3=new Student(3,"wangwu",95.0);
FileOutputStream fos = new FileOutputStream("student.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s1);
oos.writeObject(s2);
oos.writeObject(s3);
oos.close();
Student s;
FileInputStream fis = new FileInputStream("student.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
for(int i=0;i<3;i++)
{
s=(Student)ois.readObject();
System.out.println(s.num+":"+s.name+":"+s.score);
}
ois.close();
}
}
class Student implements Serializable
{
int num;
String name;
double score;
public Student(int num,String name,double score)
{
this.num=num;
this.name=name;
this.score=score;
}
}