Java總結:Java 流(Stream)、文件(File)和IO

更新時間:2018-1-7 12:27:21html

更多請查看在線文集:http://android.52fhy.com/java/index.htmljava


java.io 包幾乎包含了全部操做輸入、輸出須要的類。全部這些流類表明了輸入源和輸出目標。android

輸入輸出流

簡介

一個流被定義爲一個數據序列。輸入流用於從源讀取數據,輸出流用於向目標寫數據。windows

下圖是一個描述輸入流和輸出流的類層次圖:數組

java.io包中操做文件內容的主要有兩大類:字節流、字符流,兩類都分爲輸入和輸出操做。緩存

在字節流中輸出數據主要是使用OutputStream完成,輸入使的是InputStream;在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。這四個都是抽象類。app

java中提供了專用於輸入輸出功能的包java.io, 其中包括:ui

  • InputStream, OutputStream, Reader, Writer
  • InputStreamOutputStream, 兩個是爲字節流設計的,主要用來處理字節或二進制對象。
  • ReaderWriter, 兩個是爲字符流(1個字符佔2個字節)設計的,主要用來處理字符或字符串。

常見的System.in其實就是InputStream對象。編碼

字節流轉換爲字符流

爲了方便處理字節流,咱們常常會把字節流轉換爲字符流。例如:操作系統

Java 的控制檯輸入由 System.in 完成。爲了得到一個綁定到控制檯的字符流,咱們能夠把 System.in 包裝在一個 BufferedReader對象中來建立一個字符流。

下面是建立 BufferedReader 的基本語法:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

同理,從文件讀取:

InputStream f = new FileInputStream("C:/java/hello");
BufferedReader br = new BufferedReader(new InputStreamReader(f));

使用BufferedReader是爲了使用緩衝功能。

java.io.BufferedReaderjava.io.BufferedWriter類各擁有8192字符的緩衝區。當BufferedReader在讀取文本文件時,會先儘可能從文件中讀入字符數據並置入緩衝區,而以後若使用read()方法,會先從緩衝區中進行讀取。若是緩衝區數據不足,纔會再從文件中讀取,使用BufferedWriter時,寫入的數據並不會先輸出到目的地,而是先存儲至緩衝區中。若是緩衝區中的數據滿了,纔會一次對目的地進行寫出。

針對上面示例的三個類進行簡單說明:

  • InputStream:是全部字節輸入流的超類,通常使用它的子類:FileInputStream等,它能輸出字節流;
  • InputStreamReader:是字節流與字符流之間的橋樑,能將字節流輸出爲字符流,而且能爲字節流指定字符集,可輸出一個個的字符;
  • BufferedReader:提供通用的緩衝方式文本讀取,readLine()讀取一個文本行,從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。

InputStream提供的read()方法支持從輸入流中讀取一個數據字節。經常使用原型:

public int read() throws IOException {}

今後輸入流中讀取一個數據字節。若是沒有輸入可用,則此方法將阻塞。
指定者:類 InputStream 中的 read
返回:下一個數據字節;若是已到達文件末尾,則返回 -1。

public int read(byte[] b) throws IOException{}

今後輸入流中將最多 b.length 個字節的數據讀入一個 byte 數組中。在某些輸入可用以前,此方法將阻塞。
覆蓋:類 InputStream 中的 read
參數:存儲讀取數據的緩衝區。
返回:讀入緩衝區的字節總數,若是由於已經到達文件末尾而沒有更多的數據,則返回 -1。

示例

示例1:從控制檯讀取單字符輸入

public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    char c;
    
    System.out.println("輸入字符,按下 'q' 鍵退出:");
    
    do {
        c = (char) br.read();
        System.out.println(c);
    }while(c != 'q');
}

示例2:從控制檯讀取多字符輸入

public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s;
    System.out.println("輸入字符串,按下 'quit' 鍵退出:");
    
    do {
        s = br.readLine();
        System.out.println(s);
    }while(!s.equals("quit"));
}

示例3:使用 InputStream 中的 read讀取字節流

public static void main(String[] args) throws IOException{
    InputStream input = System.in;
    byte[] b = new byte[1024];
    int len = 0;
    StringBuffer sb = new StringBuffer("");

    while ((len = input.read(b)) != 2) {
        System.out.println(len);
        sb.append(new String(b, 0, len));
    }
    
    input.close();
    System.out.println(sb.toString());
}

其實該例子改爲文件讀取會更好:

public static void main(String[] args) throws IOException{
    InputStream input = new FileInputStream("src/test.txt");
    byte[] b = new byte[1024];
    int len = 0;
    StringBuffer sb = new StringBuffer("");

    while ((len = input.read(b)) > 0) {
        System.out.println(len);
        sb.append(new String(b, 0, len));
    }
    
    input.close();
    System.out.println(sb.toString());
}

也可使用一個文件對象來建立一個輸入流對象來讀取文件。咱們首先得使用 File() 方法來建立一個文件對象:

File f = new File("src/test.txt");
InputStream input = new FileInputStream(f);

必須先在src目錄下創建文件test.txt,內容: hello world
運行結果:

11
hello world

示例4:控制檯輸出:

咱們知道,控制檯的輸出由 print()println() 完成。這些方法都由類 PrintStream 定義,System.out 是該類對象的一個引用。
PrintStream 繼承了 OutputStream類,而且實現了方法 write()。這樣,write() 也能夠用來往控制檯寫操做。
可是write() 方法不常常使用,由於 print()println() 方法用起來更爲方便。

PrintStream 定義 write() 的最簡單格式以下所示:

void write(int byteval){}

該方法將 byteval 的低八位字節寫到流中。

public static void main(String[] args) {
    System.out.write('h');
    System.out.write('\n');
}

示例5:輸出內容到文件

public static void main(String[] args) throws IOException{
        
    String str = "hello world";
    
    // 構建FileOutputStream對象,文件不存在會自動新建
    OutputStream out = new FileOutputStream("src/test2.txt");
    out.write(str.getBytes());
    out.close();
}

也可使用一個文件對象來建立一個輸出流來寫文件。咱們首先得使用File()方法來建立一個文件對象:

File f = new File("src/test2.txt");
OutputStream out = new FileOutputStream(f);

運行後,打開src目,就能看到test2.txt。

getBytes()用於把字符串轉化爲字節流(byte型)。方法原型:

public byte[] getBytes() {
    return StringCoding.encode(value, 0, value.length);
}

public byte[] getBytes(Charset charset) {
    if (charset == null) throw new NullPointerException();
    return StringCoding.encode(charset, value, 0, value.length);
}

示例6:藉助BufferedWriter輸出內容到文件

public static void main(String[] args) throws IOException{
        
    String str = "hello";
    
    // 構建FileOutputStream對象,文件不存在會自動新建
    OutputStream out = new FileOutputStream("src/test3.txt");
    BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(out));
    bWriter.write(str);
    bWriter.close();//關閉緩衝區
}

咱們還能夠結合上述的BufferedReader進行從鍵盤輸入,保存到文件:

public static void main(String[] args) throws IOException{
        
    String str = "";
    
    // 構建FileOutputStream對象,文件不存在會自動新建
    OutputStream out = new FileOutputStream("src/test3.txt");
    BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));//構建OutputStreamWriter對象,參數能夠指定編碼,默認爲操做系統默認編碼,windows上是gbk
//      bWriter.write(str);
    
    //讀緩存區
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
    do {
        str = br.readLine();
        bWriter.write(str);
        System.out.println(str);
    }while(!str.equals("quit"));
    
    bWriter.close();//關閉緩衝區,同時會把緩衝區內容寫入文件
    out.close();// 關閉輸出流,釋放系統資源
}

文件和I/O

主要有這些類:

  • File 文件類。
  • FileReader FileReader類從InputStreamReader類繼承而來。該類按字符讀取流中數據。
  • FileWriter FileWriter 類從 OutputStreamWriter類繼承而來。該類按字符向流中寫入數據。

File 類至少有一個參數。File 類方法:

  • mkdir()方法建立一個文件夾,成功則返回true,失敗則返回false。
    失敗代表File對象指定的路徑已經存在,或者因爲整個路徑還不存在,該文件夾不能被建立。
  • mkdirs()建立指定的目錄,包括建立必需但不存在的父目錄。建立多級目錄使用該方法。
  • isDirectory()判斷是不是一個目錄。
  • isFile() 判斷是不是一個標準文件。
  • list() 提取包含的文件和文件夾的列表。
  • delete()方法同於刪除文件或空目錄。
  • createNewFile() throws IOException
    當且僅當不存在具備此抽象路徑名指定的名稱的文件時,原子地建立由此抽象路徑名指定的一個新的空文件。

示例1:目錄操做

public static void main(String[] args) throws IOException {
    String dirname = "src/tmp";
    File file = new File(dirname);
    
    //建立目錄
    if(!file.isDirectory()) {
        if(file.mkdirs()) {
            System.out.println("succ mkdirs");
        }
    }
    
    //建立文件
    File file2 = new File(dirname + "/test.txt");
    file2.createNewFile();//目錄必須存在
    
    File file3 = new File(dirname + "/test/");
    file3.mkdir();
    
    //列出目錄
    if(file.isDirectory()) {
        String[] lists = file.list();
        for (int i = 0; i < lists.length; i++) {
            File f = new File(dirname + "/" + lists[i]);
            if(f.isDirectory()) {
                System.out.println("[d]"+ lists[i]);
            }else {
                System.out.println("[f]"+ lists[i]);
            }
        }
    }else {
        System.out.println(dirname + " 不是一個目錄");
    }
    
    //刪除文件或目錄
    if(file3.delete()) {
        System.out.println("刪除成功");
    }
}

運行結果:

[d]test
[f]test.txt
刪除成功

示例2:

public static void main(String[] args) throws IOException {
    String filename = "src/tmp/test.txt";
    File file = new File(filename);
    file.createNewFile();// 建立文件
    FileWriter fWriter = new FileWriter(file);//建立FileWriter對象
    fWriter.write('i');
    fWriter.write(' ');
    char[] cs = {'l', 'o', 'v', 'e', ' '};
    fWriter.write(cs);
    fWriter.write("java");
    fWriter.flush();//將輸入流和輸出流中的緩衝進行刷新,使緩衝區中的元素即時作輸入和輸出,而沒必要等緩衝區滿
    fWriter.close();//關閉FileWriter對象
    
    //讀取文件
    FileReader fReader = new FileReader(file);
    char[] cs2 = new char[15];
    fReader.read(cs2);//這裏由於知道長度不會大於15,因此沒有用while循環讀取
    for(char c : cs2) {//遍歷輸出
        System.out.print(c);
    }
    fReader.close();

運行結果:

i love java

參考

一、Java 流(Stream)、文件(File)和IO | 菜鳥教程
http://www.runoob.com/java/java-files-io.html
二、java中char和byte的轉換 - CSDN博客
http://blog.csdn.net/feixiazhitian/article/details/49511963
三、字節流與字符流的區別及相互轉換 - 傑-維斯布魯克 - 博客園
http://www.javashuo.com/article/p-eazdohbr-ky.html
四、Java中,BufferedReader類的介紹及做用 - CSDN博客
http://blog.csdn.net/wiebin36/article/details/51912794

相關文章
相關標籤/搜索