java標準IO操作(一)
IO指的是Input,Output.即:輸入與輸出
流按照方向實際是按照功能進行劃分,參照方向是我們的程式
輸入流用於讀取,即:從外界進入程式的過程,獲取資料
輸出流用於寫出,即:程式傳送到外界的過程,傳送資料
流劃分為兩類:
節點流,處理流
節點流:又稱為低階流,是真實連線程式與資料來源的”管道”,負責實際搬運資料.讀寫一定是建立在節點流的基礎之上進行的
處理流:又稱為高階流,高階流不能獨立存在(沒有意義),一定是連線在其他流上使用的目的是通過其連線的流將資料流經此流時對資料進行加工處理,從而簡化我們實際對讀寫的資料加工的操作
流的連結:在低階流的基礎上,通過組合多個高階流在讀寫過程中完成一系列的資料加工操作的過程,稱為流的連結.
這也是java標準IO操作的精髓所在(學習重點就是學習如何組建流連結,完成一些列讀寫操作)
java.io.InputStream:所有位元組輸入流的超類,規定了所有輸入流都應當具備的讀寫位元組的相關方法
java.io.OutputStream:所有位元組輸出流的超類,規定了所有輸出流都應當具備的寫出位元組的相關方法
檔案流:是一對低階流,用來讀寫檔案資料
java.io.FileInputStream:檔案輸入流,用來向檔案中讀取位元組的流
java.io.FileOutputStream:檔案輸出流,用於向檔案中寫出位元組的流
論功能,與RandomAccessFile一致,但是RAF又能讀又能寫,而檔案流要根據做讀或寫操作選取輸入或輸出流進行.
並且它們的底層實際讀寫操作是不一樣的,RAF是基於指標對檔案進行讀寫,所以可以根據指標進行部分覆蓋寫操作等,
做到對檔案資料編輯操作.但是流做不到,因為流是[順序讀寫]操作.所以對於靈活性而言,RAF是優於檔案流的.但是檔案流基於IO操作可以通過連線不同高階流更輕鬆的完成複雜的讀寫操作
對於讀寫檔案而言:
RAF是基於指標的讀寫,稱為”隨機讀寫”.可以移動指標對任意位置讀寫操作.
檔案流是流的讀寫方式,而流是”順序讀寫”,只能順序往後讀寫操作,是不能回退操作的.
FOS演示
public class FOSDemo {
public static void main(String[] args) throws IOException {
/*
* 檔案輸出流創建出來,預設為覆蓋模式
* 即:當操作檔案已經存在,那麼在建立號檔案輸出流時會先將該檔案所有資料清除. 然後通過該流寫出的所有資料作為檔案資料
*
* 檔案流還支援過載構造方法,在第一個引數基礎上可以再傳入一個boolean型別的引數,當該值為true時,即是追加模式
* 即:檔案原有資料全部保留,通過該流寫出的資料會被追加到檔案末尾
*/
FileOutputStream fos = new FileOutputStream("fos.txt"); //預設覆蓋模式
//FileOutputStream fos = new FileOutputStream("fos.txt",true); //追加模式
String line = "一天天天天天";
byte[] data = line.getBytes("GBK");
fos.write(data);
line = ",一月月月月月";
data = line.getBytes("GBK");
fos.write(data);
System.out.println("寫出完畢");
fos.close();
}
}
FIS演示
public class FISDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
byte[] data = new byte[1024];
int len = fis.read(data);
String str = new String(data,0,len,"GBK");
System.out.println(str);
fis.close();
}
}
使用檔案流完成檔案的複製操作
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
/*
* 步驟:
* 1.建立檔案輸入流用於讀取原檔案
* 2.建立檔案輸出流用於寫出複製檔案
* 3.順序從原檔案讀取位元組並寫入到複製檔案中完成複製操作
*/
FileInputStream fis = new FileInputStream("fos.txt");
FileOutputStream fos = new FileOutputStream("fos_copy.txt");
byte[] data = new byte[1024];
int len = -1;
while((len=fis.read(data))!=-1){
fos.write(data,0,len);
}
System.out.println("操作完畢");
fos.close();
fis.close();
}
}
處理流,也稱高階流
在IO操作中,通常我們會在低階流上連線一些高階流,
這樣當資料流經這些高階流時,它們可以對資料進行相應的加工處理,
以簡化我們對資料的相關操作.而這個過程,稱為流連結處理
緩衝流
緩衝流是一對高階流,作用是提高讀寫效率.
緩衝流內部維護一個數組,無論我們做隨機讀寫還是塊讀寫操作,最終都會在流經緩衝流時改變為塊讀寫操作,從而提高了讀寫效率
緩衝流演示
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("movie.mp4");
FileOutputStream fos = new FileOutputStream("movie_copy.mp4");
//連線緩衝位元組輸出流,提高讀寫效率
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d=-1;
while((d = bis.read())!=-1){
bos.write(d);
}
System.out.println("複製完成");
/*
* 關閉流的時候,只需要關閉最外層高階流即可
*
*/
bis.close();
bos.close();
}
}
緩衝輸出流的緩衝區問題
public class BOS_flush {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bos.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String line = "秒針轉動,滴滴答";
byte[] data = line.getBytes();
bos.write(data);
/*
* void flush()
* 緩衝流的flush方法用於強制將緩衝區中已快取的資料進行一次性寫出.
* 頻繁的呼叫flush方法會降低寫效率,但是能保證寫出資料的即時性
*/
//bos.flush();
System.out.println("寫出完畢");
//close方法中有一次flush操作
bos.close();
}
}
物件流
java.io.ObjectOutputStream
java.io.ObjectInputStream
物件流是一對高階流,使用它們可以很方便的進行java中任何物件的讀寫操作
public class OOSDemo {
public static void main(String[] args) throws IOException {
String name = "nick";
int age = 18;
String gender = "man";
String[] otherInfo = {"A","B","C"};
Person person = new Person(name,age,gender,otherInfo);
/*
* 將person物件寫入檔案"person.obj"
*/
FileOutputStream fos = new FileOutputStream("person.obj");
/*
* 為了方便寫出物件,連線物件輸出流
*/
ObjectOutputStream oos = new ObjectOutputStream(fos);
/*
*物件輸出流提供方法
*void writeObject(Object obj)
*該方法用於將給定物件轉換為一組位元組後寫出
*需要注意,寫出的物件必須實現介面:Serializable,否則會丟擲異常
*/
oos.writeObject(person);
System.out.println("寫出完畢");
oos.close();
}
}