天天看點

Java入門 - 語言基礎 - 20.Stream和File和IOStream和File和IO

原文位址: http://www.work100.net/training/java-stream-file-io.html 更多教程: 光束雲 - 免費課程

Stream和File和IO

序号 文内章節 視訊
1 概述 -
2 流(Stream) )
3 讀寫檔案
4 檔案和I/O

請參照如上

章節導航

進行閱讀

1.概述

Java.io

包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目标。

Java.io

包中的流支援很多種格式,比如:基本類型、對象、本地化字元集等等。

一個流可以了解為一個資料的序列。輸入流表示從一個源讀取資料,輸出流表示向一個目标寫資料。

Java 為

I/O

提供了強大的而靈活的支援,使其更廣泛地應用到檔案傳輸和網絡程式設計中。

但本節講述最基本的和流與

I/O

相關的功能。我們将通過一個個例子來學習這些功能。

2.流(Stream)

2.1.讀取控制台輸入

Java 的控制台輸入由

System.in

完成。

為了獲得一個綁定到控制台的字元流,你可以把

System.in

包裝在一個

BufferedReader

對象中來建立一個字元流。

下面是建立

BufferedReader

的基本文法:

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

BufferedReader

對象建立後,我們便可以使用

read()

方法從控制台讀取一個字元,或者用

readLine()

方法讀取一個字元串。

2.2.從控制台讀取多字元輸入

BufferedReader

對象讀取一個字元要使用

read()

方法,它的文法如下:

int read( ) throws IOException           

每次調用

read()

方法,它從輸入流讀取一個字元并把該字元作為整數值傳回。 當流結束的時候傳回

-1

。該方法抛出

IOException

下面的程式示範了用

read()

方法從控制台不斷讀取字元直到使用者輸入 "

q

"。

//使用 BufferedReader 在控制台讀取字元
 
import java.io.*;
 
public class BRRead {
    public static void main(String[] args) throws IOException {
        char c;
        // 使用 System.in 建立 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("輸入字元, 按下 'q' 鍵退出。");
        // 讀取字元
        do {
            c = (char) br.read();
            System.out.println(c);
        } while (c != 'q');
    }
}           

以上執行個體編譯運作結果如下:

輸入字元, 按下 'q' 鍵退出。
work100
w
o
r
k
1
0
0


q
q           

2.3.從控制台讀取字元串

從标準輸入讀取一個字元串需要使用

BufferedReader

readLine()

方法。

它的一般格式是:

String readLine( ) throws IOException           

下面的程式讀取和顯示字元行直到你輸入了單詞"

end

//使用 BufferedReader 在控制台讀取字元
import java.io.*;
 
public class BRReadLines {
    public static void main(String[] args) throws IOException {
        // 使用 System.in 建立 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        System.out.println("Enter lines of text.");
        System.out.println("Enter 'end' to quit.");
        do {
            str = br.readLine();
            System.out.println(str);
        } while (!str.equals("end"));
    }
}           
Enter lines of text.
Enter 'end' to quit.
This is line one
This is line one
This is line two
This is line two
end
end           
JDK 5 後的版本我們也可以使用 Java Scanner 類來擷取控制台的輸入。

2.4.控制台輸出

在此前已經介紹過,控制台的輸出由

print()

println()

完成。這些方法都由類

PrintStream

定義,

System.out

是該類對象的一個引用。

PrintStream

繼承了

OutputStream

類,并且實作了方法

write()

。這樣,

write()

也可以用來往控制台寫操作。

PrintStream

定義

write()

的最簡單格式如下所示:

void write(int byteval)           

該方法将

byteval

的低八位位元組寫到流中。

執行個體

下面的例子用

write()

把字元 "

A

" 和緊跟着的換行符輸出到螢幕:

import java.io.*;
 
//示範 System.out.write().
public class WriteDemo {
    public static void main(String[] args) {
        int b;
        b = 'A';
        System.out.write(b);
        System.out.write('\n');
    }
}           

運作以上執行個體在輸出視窗輸出 "

A

" 字元

A           
注意:

write()

方法不經常使用,因為

print()

println()

方法用起來更為友善。

3.讀寫檔案

如前所述,一個流被定義為一個資料序列。輸入流用于從源讀取資料,輸出流用于向目标寫資料。

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

Java入門 - 語言基礎 - 20.Stream和File和IOStream和File和IO

下面将要讨論的兩個重要的流是

FileInputStream

FileOutputStream

3.1.FileInputStream

該流用于從檔案讀取資料,它的對象可以用關鍵字

new

來建立。

有多種構造方法可用來建立對象。

可以使用字元串類型的檔案名來建立一個輸入流對象來讀取檔案:

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

也可以使用一個檔案對象來建立一個輸入流對象來讀取檔案。我們首先得使用

File()

方法來建立一個檔案對象:

File f = new File("C:/java/hello");
InputStream out = new FileInputStream(f);           

建立了

InputStream

對象,就可以使用下面的方法來讀取流或者進行其他的流操作。

方法及描述

public void close() throws IOException{}

關閉此檔案輸入流并釋放與此流有關的所有系統資源。抛出

IOException

異常。

protected void finalize()throws IOException{}

這個方法清除與該檔案的連接配接。確定在不再引用檔案輸入流時調用其

close

方法。抛出

IOException

public int read(int r)throws IOException{}

這個方法從

InputStream

對象讀取指定位元組的資料。傳回為整數值。傳回下一位元組資料,如果已經到結尾則傳回

-1

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

這個方法從輸入流讀取

r.length

長度的位元組。傳回讀取的位元組數。如果是檔案結尾則傳回

-1

5

public int available() throws IOException{}

傳回下一次對此輸入流調用的方法可以不受阻塞地從此輸入流讀取的位元組數。傳回一個整數值。

3.2.FileOutputStream

該類用來建立一個檔案并向檔案中寫資料。

如果該流在打開檔案進行輸出前,目标檔案不存在,那麼該流會建立該檔案。

有兩個構造方法可以用來建立

FileOutputStream

對象。

使用字元串類型的檔案名來建立一個輸出流對象:

OutputStream f = new FileOutputStream("C:/java/hello")           

也可以使用一個檔案對象來建立一個輸出流來寫檔案。我們首先得使用

File()

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);           

建立

OutputStream

對象完成後,就可以使用下面的方法來寫入流或者進行其他的流操作。

public void close() throws IOException{}

IOException

protected void finalize()throws IOException{}

close

IOException

public void write(int w)throws IOException{}

這個方法把指定的位元組寫到輸出流中。

public void write(byte[] w)

把指定數組中

w.length

長度的位元組寫到

OutputStream

中。

除了

OutputStream

外,還有一些其他的輸出流:

  • ByteArrayOutputStream

  • DataOutputStream

下面是一個示範

InputStream

OutputStream

用法的例子:

import java.io.*;
 
public class fileStreamTest {
    public static void main(String[] args) {
        try {
            byte bWrite[] = { 11, 21, 3, 40, 5 };
            OutputStream os = new FileOutputStream("test.txt");
            for (int x = 0; x < bWrite.length; x++) {
                os.write(bWrite[x]); // writes the bytes
            }
            os.close();
 
            InputStream is = new FileInputStream("test.txt");
            int size = is.available();
 
            for (int i = 0; i < size; i++) {
                System.out.print((char) is.read() + "  ");
            }
            is.close();
        } catch (IOException e) {
            System.out.print("Exception");
        }
    }
}           

上面的程式首先建立檔案

test.txt

,并把給定的數字以二進制形式寫進該檔案,同時輸出到控制台上。

以上代碼由于是二進制寫入,可能存在亂碼,你可以使用以下代碼執行個體來解決亂碼問題:

//檔案名 :fileStreamTest2.java
import java.io.*;
 
public class fileStreamTest2 {
    public static void main(String[] args) throws IOException {
 
        File f = new File("a.txt");
        FileOutputStream fop = new FileOutputStream(f);
        // 建構FileOutputStream對象,檔案不存在會自動建立
 
        OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
        // 建構OutputStreamWriter對象,參數可以指定編碼,預設為作業系統預設編碼,windows上是gbk
 
        writer.append("中文輸入");
        // 寫入到緩沖區
 
        writer.append("\r\n");
        // 換行
 
        writer.append("English");
        // 重新整理緩存沖,寫入到檔案,如果下面已經沒有寫入的内容了,直接close也會寫入
 
        writer.close();
        // 關閉寫入流,同時會把緩沖區内容寫入檔案,是以上面的注釋掉
 
        fop.close();
        // 關閉輸出流,釋放系統資源
 
        FileInputStream fip = new FileInputStream(f);
        // 建構FileInputStream對象
 
        InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
        // 建構InputStreamReader對象,編碼與寫入相同
 
        StringBuffer sb = new StringBuffer();
        while (reader.ready()) {
            sb.append((char) reader.read());
            // 轉成char加到StringBuffer對象中
        }
        System.out.println(sb.toString());
        reader.close();
        // 關閉讀取流
 
        fip.close();
        // 關閉輸入流,釋放系統資源
    }
}           

4.檔案和I/O

還有一些關于檔案和

I/O

的類,我們也需要知道:

  • File

    Class(類)
  • FileReader

  • FileWriter

Java中的目錄

建立目錄:

File

類中有兩個方法可以用來建立檔案夾:

  • mkdir()

    方法建立一個檔案夾,成功則傳回

    true

    ,失敗則傳回

    false

    。失敗表明

    File

    對象指定的路徑已經存在,或者由于整個路徑還不存在,該檔案夾不能被建立
  • mkdirs()

    方法建立一個檔案夾和它的所有父檔案夾

下面的例子建立 "

/tmp/user/java/bin

"檔案夾:

import java.io.File;
 
public class CreateDir {
    public static void main(String[] args) {
        String dirname = "/tmp/user/java/bin";
        File d = new File(dirname);
        // 現在建立目錄
        d.mkdirs();
    }
}           

編譯并執行上面代碼來建立目錄 "

/tmp/user/java/bin

注意: Java 在

UNIX

Windows

自動按約定分辨檔案路徑分隔符。如果你在

Windows

版本的 Java 中使用分隔符 (

/

) ,路徑依然能夠被正确解析。

讀取目錄

一個目錄其實就是一個

File

對象,它包含其他檔案和檔案夾。

如果建立一個

File

對象并且它是一個目錄,那麼調用

isDirectory()

方法會傳回

true

可以通過調用該對象上的

list()

方法,來提取它包含的檔案和檔案夾的清單。

下面展示的例子說明如何使用

list()

方法來檢查一個檔案夾中包含的内容:

import java.io.File;
 
public class DirList {
    public static void main(String[] args) {
        String dirname = "/tmp";
        File f1 = new File(dirname);
        if (f1.isDirectory()) {
            System.out.println("目錄 " + dirname);
            String s[] = f1.list();
            for (int i = 0; i < s.length; i++) {
                File f = new File(dirname + "/" + s[i]);
                if (f.isDirectory()) {
                    System.out.println(s[i] + " 是一個目錄");
                } else {
                    System.out.println(s[i] + " 是一個檔案");
                }
            }
        } else {
            System.out.println(dirname + " 不是一個目錄");
        }
    }
}           

以上執行個體編譯運作結果如下:

目錄 /tmp
bin 是一個目錄
lib 是一個目錄
demo 是一個目錄
test.txt 是一個檔案
README 是一個檔案
index.html 是一個檔案
include 是一個目錄           

删除目錄或檔案

删除檔案可以使用

java.io.File.delete()

以下代碼會删除目錄

/tmp/java/

,需要注意的是當删除某一目錄時,必須保證該目錄下沒有其他檔案才能正确删除,否則将删除失敗。

測試目錄結構:

/tmp/java/
|-- 1.log
|-- test           
import java.io.File;
 
public class DeleteFileDemo {
    public static void main(String[] args) {
        // 這裡修改為自己的測試目錄
        File folder = new File("/tmp/java/");
        deleteFolder(folder);
    }
 
    // 删除檔案及目錄
    public static void deleteFolder(File folder) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) {
                    deleteFolder(f);
                } else {
                    f.delete();
                }
            }
        }
        folder.delete();
    }
}           

上一篇:

方法

下一篇:

Scanner類
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java入門 - 語言基礎 - 20.Stream和File和IOStream和File和IO
Java入門 - 語言基礎 - 20.Stream和File和IOStream和File和IO