1. 程式人生 > 實用技巧 >2020.8.1

2020.8.1

一、今日學習內容

1、流和流的分類

(1)在Java中,每個流都是一個物件。 流通常分為兩種:輸入流(InputStream) 和輸出流(OutputStream)。對於輸入流,只要從流當中不停地把位元組取出即可;而對於輸出流,只要把準備好的位元組串傳給它即可,如圖所示。

java.io包中的stream類根據其操作物件的型別可分為兩大類:字元流和位元組流。
a. Java的位元組流
InputStream是所有位元組輸入流的父類,而OutputStream是所有位元組輸出流的父類。
b. Java 的字元流
Reader是所有讀取字串輸入流的父類,而Writer 是所有輸出字串的父類。

結合開始所說的輸入/輸出流,出現了一個小框架。
位元組流 字元流
輸入流 InputStream Reader
輸出流OutputStream Writer
位元組流和字元流如圖所示。

從該圖可以看出,在Java中,所有的位元組流都是以Stream結尾的,所有的字元流都是以Reader/Writer結尾的。

(2)位元組流和字元流

Java對於流的操作可以分為位元組流和字元流。位元組流主要操作位元組序列的物件,如對二進位制檔案、圖片及影像檔案的操作;字元流主要操作字元序列的物件,如對文字 檔案等。

1.位元組流
(1)輸出位元組流OutputStream
I/O中輸出位元組流的繼承圖所示,可以看出以下特點。
#OutputStream是所有的輸出位元組流的父類,它是一個抽象類。
#ByteArrayOutputStream、FileOutputStream是兩種基本的介質流,它們分別向Byte陣列和本地檔案中寫入資料。ObjectOutputStream和所有 FilterOutputStream的子類都是裝飾流。
使用位元組輸出流OutputStream定義如下。

public abstract class
OutputStream extends object implements Closeable,Flushable

在此類中定義瞭如下的幾個常用方法。
#關閉流:publicvoidclose() throwsIOException.
#寫一組資料:publicvoidwrite(byte[]b)throwsIOException.
#寫一個數據:publicvoidwrite(intb)throwsIOException。但是要想將Outputream例項化,且進行檔案操作,就要使用FileOutputStream子類。
#構造:publicFileOutputStream(Filefile)throwsFileNotFoundException.
示例:使用位元組流輸出內容

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileOutStreamDemo {
    public static void main(String[] args)throws IOException {
        out();
    }
    public static void out()throws IOException{
        OutputStream out=new FileOutputStream("D:/Hello.txt");
        String info="Hello Java!";
        byte[] buf=info.getBytes();
        out.write(buf);
        out.close();
    }
}

示例:使用位元組流追加內容

該程式還會有一個問題,如果在關閉前程式出現異常,檔案就不能關閉,所以應該將關閉放在finally裡,不管程式有無異常,都應該關閉流,程式碼修改如下。

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileOutStreamDemo {
    public static void main(String[] args)throws IOException {
        out();
    }
    public static void out(){
        OutputStream out=null;
        try {
           out=new FileOutputStream("D:/Hello.txt",true);
           String info="Hello PHP!";
           byte[] buf=info.getBytes();
           out.write(buf);
        }catch(IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null) out.close();
            }catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
}

(2)輸入位元組流InputStream
I/O中輸入位元組流的繼承圖所示,可以看出:
#InputStream 是所有的輸入位元組流的父類,它是一個抽象類。
#ByteArrayInputStream、 StringBufferInputStream. FileInputStream 是三種基本的介質流,它們分別從Byte陣列、StringBuffer 和本地檔案中讀取資料。 ObjectInputStream和所有FilterInputStream的子類都是裝飾流。
使用者可以使用InputStream完成輸入位元組流的操作,此類定義如下。

public abstract class InputStream extends object implements Closeable

InputStream類中定義的方法如下。
#關閉: public void closeO throws IOException.
#讀取一個位元組: public abstract int read() throws IOException.
#讀取一組內容: public int read(byte[] b) throws IOException.
讀取檔案,使用子類FileInputStream。
示例:使用位元組流讀檔案內容

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileInputStreamDemo {
    public static void main(String[] args)throws IOException {
        in();
    }
    public static void in() {
        FileInputStream in=null;
        try {
           in=new FileInputStream("D:/Hello.txt");
           byte[] buf=new byte[1024];
           int len=-1;
           while((len=in.read(buf))!=-1) {
               String s=new String(buf,0,len);
               System.out.println(s);
           }
        }catch(IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(in!=null) in.close();
            }catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
}

輸出結果:Hello Java!Hello PHP!

2、字元流

Reader與Writer和其子類都是處理字元流的相關類。字元流可以對流資料以一個字元的長度為單位來處理,並進行適當的字元編碼轉換處理,- -般字元流都用來操作純文字檔案。
(1)字元輸出流。
Writer是字元輸出流,該類是一個抽象類,所以需要使用子類FileWriter類來操作檔案。
示例:字元輸出流寫入內容

import java. io. FileWriter;
import java.io. IOException;
public class WriteDemo {
    public static void main(String[] args) throws IOException {
      write() ;
    }
    public static void write() throws IOException{
       FileWriter fw =new FileWriter ("D:/Hello.txt") ;
       fw. write("Hello C++!");
       fw.close() ;
    }
}

若在檔案中追加內容,且原內容不被覆蓋,則

import java. io. FileWriter;
import java.io. IOException;
public class WriteDemo {
    public static void main(String[] args) throws IOException {
      write() ;
    }
    public static void write() throws IOException{
       FileWriter fw =new FileWriter ("D:/Hello.txt",true) ;
       fw. write("Hello C++!");
       fw.close() ;
    }
}

(2)字元輸入流

Reader是一個字元輸入流,但它是-個抽象類,所以必須由其子類FileReader來例項化。
示例:使用字元輸入流讀取內容

import java. io. FileReader;
import java.io. IOException;
import java. io. Reader;
public class WriteDemo {
    public static void main(String[] args) throws IOException {
     reader() ;
    }
    public static void reader() throws IOException{
      Reader r =new FileReader ("D:/Hello.txt") ;
      char[] buf=new char[1024];
      int len=0;
      while((len=r.read(buf)!=-1){
          String s=new String(buf,0,len);
          System.out.println(s);
      }
      r.close();
   }
}

輸出結果:Hello C++!

3.位元組流與字元流的區別
位元組流與字元流的區別主要體現在以下兩點。
#讀寫單位不同:位元組流以位元組(8bit) 為單位,字元流以字元為單位,根據碼錶對映字元,一次可能讀多個位元組。
#處理物件不同:位元組流能處理所有型別的資料(如圖片、avi等), 而字元流只能處理字元型別的資料。
結論:只要是處理純文字資料,就優先考慮使用字元流,此外,都使用位元組流。

二、遇到的問題

內容較多,不能記得很清楚,對位元組流字元流理解的也不是很清楚

三、明日計劃

繼續學習第12章的內容