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;
}
}