1.流的分類
(1)流按照是否直接與特定地方(如磁盤、記憶體、裝置、網絡)連接配接,分為節點流和處理流。
節點流:直接從一個特定的地方(節點)讀寫資料。
處理流:包裹在節點流上,處理流的構造方法總是帶一個其他的流的對象作為參數。
(2)流按照方向分為:輸入流和輸出流
輸入流:從外界進入到程式的方向,用來讀取外界的資料。
輸出流:從程式發送到外界的方向,用來寫出資料到外界。
2.常用的流
(1)InputStream和OutputStream
InputStream是所有位元組輸入流的父類,OutputStream是所有位元組輸出流的父類。
(2)檔案流FileInputStream和FileOutputStream,是檔案位元組輸入流和檔案位元組輸出流。
FileOutputStream按位元組讀取檔案操作
/**
* java.io.FileOutputStream
* 檔案位元組輸出流,是一個低級流
* 用于向檔案中寫入位元組
* @author zc
*/
public class T01FileOutputStream {
public static void main(String[] args) {
File file=new File("fos.txt");
try {
//如果檔案不存在,fos會建立,預設會覆寫寫操作,源檔案中内容全部清除
/*
* FileOutputStream預設的構造方法是預設寫操作,即:
* 若要寫出的檔案已經存在,會先将該檔案中的原有資料全部清除,
* 然後在通過該流寫出新的資料
* */
FileOutputStream fos=new FileOutputStream(file);
fos.write("簡單點".getBytes());
/*
* 追加寫操作,該構造方法需要傳入第二個參數,該參數為一個boolean值,若
* 該值為true,則具有追加寫操作的能力,那麼通過該流寫出的内容會被追加到該問價你的末尾
* */
FileOutputStream fos2=new FileOutputStream(file,true);
fos2.write("第二次寫".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream按位元組讀取檔案操作
public class T02FileInputStream {
public static void main(String[] args) {
//java.io.FileNotFoundException: fos.txt (系統找不到指定的檔案。)如果檔案不存在
File file=new File("fos.txt");
try {
FileInputStream fis=new FileInputStream(file);
byte[] b=new byte[24];
int len;//len為每次讀取到的長度,讀的内容存放在b裡
while((len=fis.read(b))!=-1){
System.out.println(new String(b,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FileInputStream和FileOutputStream聯合實作檔案按位元組複制操作
public class T03FileCopy {
public static void main(String[] args) {
FileOutputStream fos=null;
FileInputStream fis=null;
try {
fos=new FileOutputStream(new File("myoutput_copy.txt"));
fis=new FileInputStream(new File("fos.txt"));
byte[] b=new byte[24];
int len;
while((len=fis.read(b))!=-1){
fos.write(b,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)緩沖流是一種處理流,在讀寫操作時,使用緩沖流可以在記憶體中緩沖一些資料,一次性寫出,減少寫出次數,進而達到調讀寫效率的目的。
BufferedInputStream:位元組緩沖輸入流 BufferedOutputStream():位元組緩沖輸出流 BufferedReader():字元緩沖輸入流 BufferedWriter():字元緩沖輸出流
public class T04Buffered {
public static void main(String[] args) {
File src=new File("myemp.txt");
File desc=new File("myemp_copy.txt");
FileInputStream fis=null;
FileOutputStream fos=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
fis=new FileInputStream(src);
fos=new FileOutputStream(desc);
//進階流關了,會自動關閉低級流
/*
* 緩沖流内部維護了一個緩沖區,當我們調用下面read()方法讀取一個位元組時,實際上
* 緩沖流讓fis讀取一組位元組并存入到緩沖流自身内部的位元組數組中,然後将第一個位元組傳回.
* 當我們再次調用read()方法
* 讀取一個位元組時,緩沖流會将位元組數組中第二個位元組傳回,
* 以此類推,直到該數組中所有位元組都被讀取過後才會再次讀取一組位元組
* 是以實際上還是通過提高每次讀取資料的數量來減少讀取的次數提高的讀取效率
*
* */
bis=new BufferedInputStream(fis);
bos=new BufferedOutputStream(fos);
byte[] b=new byte[1024];
int len;
while((len=bis.read(b))!=-1){
bos.write(b,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedOutputStream的flush方法
使用緩沖輸出流可以提高寫出效率,但是這也存在着一個問題,就是寫出資料缺乏即時性。有時我們需要在執行完某些寫出操作後,就希望将這些資料确實寫出,而非在緩沖區中儲存直到緩沖區滿後才寫出。這時我們可以使用緩沖流的一個方法flush。
/**
* @author zc
*/
public class T05BufferedFlush {
public static void main(String[] args) {
/*
* 通過緩沖輸出流寫出的位元組并不會立刻被寫入檔案,
* 會先存入其内部的位元組數組,知道該數組滿了,
* 才會一次性寫出所有資料,這樣做等同于提高寫出資料量
* 減少寫出次數提高寫出效率
*
* flush方法可以強制将緩沖區已有的資料一次性寫出,
* 這樣可以提高及時性,但是頻繁操作會導緻寫出次數提高降低寫出效率
* */
BufferedOutputStream bos=null;
FileOutputStream fos=null;
File file=new File("flush.txt");
try {
fos=new FileOutputStream(file);
bos=new BufferedOutputStream(fos);
bos.write("我愛中國".getBytes());
//添加flush會強制輸出緩存中的内容
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}