IO流
按照功能分爲:
1. 輸入流
- 從外界獲取數據,讀取數據
2. 輸出流
- 向外界發送數據,寫入數據
按照處理字節分爲:
1. 節點流
- 又稱爲低級流
- 可以從或向一個特定的地方(節點)讀寫數據
2. 處理流
- 又稱爲高級流
- 不能獨立存在,構造方法需要傳入另一個流
- 需要處理另一個流//這個流可能是低級流,也可以是高級流。
- 簡化讀寫操作
IS和OS常用方法
InputStream和OutputStream是抽象類,他們是所有字節輸入流和輸出流的父類。
OutputStream
1. void write (int d)
- 寫處一個字節,int的低八位
2. void write(byte [] d)
- 將給定的字節數組中所有字節全部寫出
低級流實現類:FOS&FIS
1.FileOutputStream
- 節點流,用於向文件中寫出字節的流
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("fos.dat");
fos.write(97);
String str ="天安門上太陽升";
byte [] buf=str.getBytes("UTF-8");
fos.write(buf);
fos.close();
}
1.FileInputStream
- 節點流,用於從文件中讀取字節的流
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("fos.dat");
int i=fis.read();
System.out.println(i);
byte [] buf=new byte[30];
int len =fis.read(buf);
String str=new String(buf,"UTF-8");
System.out.println(len);
System.out.println(str);
fis.close();
}
使用文件字節輸出流對已有文件進行寫操作的注意事項
- FileOutputStream支持一個重載的構造方法
FileOutputStream(String str,boolean append)
第二個參數決定是否進行追加操作,
若不追加,當前文件所有內容都會被清除,然後重寫數據。
要注意這一點和RandomAccessFile不同
使用FIS和FOS複製文件
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("src.jpg");
FileOutputStream fos=new FileOutputStream("copy.jpg");
byte [] buf=new byte[10240];
int len=-1;
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
System.out.println("複製完畢");
fis.close();
fos.close();
}
簡單高級流實現類:BOS&BIS
- BufferedOutputStream和BufferedInputStream緩衝流是高級流
- 使用緩衝流可以加快讀寫效率
- 關閉流時,僅關閉最外層高級流即可
public static void main(String[] args) throws IOException {
FileOutputStream fos =new FileOutputStream("src.jpg");
BufferedOutputStream bos=new BufferedOutputStream(fos);
FileInputStream fis=new FileInputStream("copy.jpg");
BufferedInputStream bis =new BufferedInputStream(fis);
int d=-1;
while((d=bis.read())!=-1){
bos.write(d);
}
bos.close();
bis.close();
}
flush()
- 強制將當前緩衝流的緩衝區的數據全部寫出,無論緩衝區是否裝滿
- 緩衝流的close();方法默認調用一次flush(),再關閉緩衝流處理的流。
- 雖然關閉高級流會自動flush();但在注意時效性時候也需要自己flush();
ObjectOutputStream
寫字符串到硬盤中要經歷兩件事
- 將字符串轉換成一組字節
- 將以組字節寫入硬盤長久保留
- 將一個特定的數據結構轉換成一組字節的過程,稱之爲序列化
- 將數據寫入硬盤做長久保存的過程,稱爲持久化
序列化與反序列化一般用於:
- 傳輸
- 保存
void wreiteObject(Object o)
- 將給定的對象轉換爲一組字節後寫出
- 想要被拆的對象的類需要實現接口Serializable,實現該接口不需要寫任何方法
ObjectInputStream
- 高級流,可以將以組字節變爲對應的對象
- 用於對象的反序列化
readObject()
- 返回值類型爲Object
- 可以強制轉換爲需要的類型
transient 關鍵字
- java語言的關鍵字,變量修飾符,如果用transient聲明一個實例變量,當對象存儲時,它的值不需要維持。換句話來說就是,用transient關鍵字標記的成員變量不參與序列化過程。
- 反序列化回來是該變量類型的默認值
long型常量serialVersionUID
- static final long
- 名字不可改
- 代表版本號默認值1L
- 如果版本號相同,在刪除成員變量或增加成員變量後,反序列化仍能進行
- 刪除成員變量則直接不顯示,增加的成員變量,反序列化付給該類型的初始值
- 若版本號不同,就不能反序列化。
- 總結
當累的屬性增加或修改了,若版本號不變那麼反序列化時會儘可能兼容現有版本
若版本號變化那麼反序列化會拋出異常。