Java檔和輸入和輸出(I/O)

java.io包幾乎包含了在Java中執行輸入和輸出(I/O)所需的所有類。 所有這些流代表輸入源和輸出目的地。 java.io包中的流支持許多數據,如:原始,對象,本地化字元等。

1. 流(Streams)

流(Streams)可以定義為數據序列,它有兩種 -

  • InPutStream - 它用於從源讀取數據。
  • OutPutStream - 它用於將數據寫入目標。

Java流

Java為與檔和網路相關的I/O提供強大而靈活的支持,但本教程只涵蓋了流和I/O相關的非常基本的功能。下麵將看到一些最常用的例子 -

1.1. 位元組流
Java位元組流用於執行8位位元組的輸入和輸出。儘管有許多與位元組流相關的類,但最常用的類是FileInputStreamFileOutputStream。以下示例使用這兩個類將輸入檔的內容複製到輸出檔中 -

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileInputStream in = null;
      FileOutputStream out = null;

      try {
         in = new FileInputStream("D:\\input.txt");
         out = new FileOutputStream("D:\\output.txt");
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

假設在D盤下有一個檔:input.txt,它的內容如下 -

This is test for copy file.
power by xuhuhu.com

下一步,編譯上面的程式並執行它,它將創建一個:D:/output.txt檔,內容與D:/input.txt中的相同。

1.2. 字元流

Java位元組流用於執行8位位元組的輸入和輸出,而Java字元流用於執行16位unicode的輸入和輸出。 儘管有許多與字元流相關的類,但最常用的類是FileReaderFileWriter。 雖然FileReader內部使用FileInputStream類,而FileWriter內部使用FileOutputStream類,但主要區別在於FileReader一次讀取兩個位元組,而FileWriter一次寫入兩個位元組。

可以重新編寫上面的例子,它使用這兩個類將輸入檔(具有unicode字元)複製到輸出檔中 -

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;

      try {
         in = new FileReader("D:/input.txt");
         out = new FileWriter("D:/output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

假設在D盤下有一個檔:input.txt,它的內容如下 -

This is test for copy file.
power by xuhuhu.com

下一步,編譯上面的程式並執行它,它將創建一個:D:/output.txt檔,內容與D:/input.txt中的相同。

2. 標準流

所有編程語言都支持標準I/O,用戶的程式可以從鍵盤輸入,然後在電腦螢幕上產生輸出。 如果您瞭解C或C++編程語言,那麼應該瞭解三個標準流:STDINSTDOUTSTDERR。 同樣,Java提供以下三個標準流 -

  • 標準輸入 - 用於將數據提供給用戶程式,通常鍵盤用作標準輸入流並表示為System.in
  • 標準輸出 - 用於輸出用戶程式生成的數據,通常電腦螢幕用於標準輸出流並表示為System.out
  • 標準錯誤 - 用於輸出用戶程式生成的錯誤數據,通常電腦螢幕用於標準錯誤流並表示為System.err

以下是一個簡單的程式,它使用InputStreamReader來讀取標準輸入流,直到用戶鍵入:q -

import java.io.*;
public class ReadConsole {

   public static void main(String args[]) throws IOException {
      InputStreamReader cin = null;

      try {
         cin = new InputStreamReader(System.in);
         System.out.println("Enter characters, 'q' to quit>");
         char c;
         do {
            c = (char) cin.read();
            System.out.print(c);
         } while(c != 'q');
      }finally {
         if (cin != null) {
            cin.close();
         }
      }
   }
}

將上面的代碼保存在ReadConsole.java檔中,並嘗試編譯並執行它,如下面的程式所示。 程式繼續讀取並輸出用戶輸入的字元,直到按q退出 -

$javac ReadConsole.java
$java ReadConsole
Enter characters, 'q' to quit>
1
1
a
a
C
C

3. 讀寫檔

如前所述,流可以定義為數據序列。 InputStream用於從源讀取數據,OutputStream用於將數據寫入目標。

以下是處理輸入和輸出流的類層次結構。

輸入和輸出流

兩個重要的流是:FileInputStreamFileOutputStream,將在本教學中討論。

3.1. FileInputStream

此流用於從檔中讀取數據。 可以使用關鍵字new創建對象,並且有幾種類型的構造函數可用。

以下構造函數將檔案名作為字串來創建輸入流對象以讀取檔 -

InputStream f = new FileInputStream("D:/java/hello.txt");

以下構造函數採用檔對象來創建輸入流對象以讀取檔。 首先,使用File()方法創建一個檔對象,如下所示 -

File f = new File("D:/java/hello.txt");
InputStream f = new FileInputStream(f);

當創建了InputStream對象,就可以使用一些輔助方法來讀取流或在流上執行其他操作。

編號 方法 描述
1 public void close() throws IOException{} 此方法關閉檔輸出流。 釋放與該檔關聯的所有系統資源,拋出IOException
2 protected void finalize()throws IOException {} 此方法清除與檔的連接。 確保在沒有對此流的引用時調用此檔輸出流的close()方法,拋出IOException
3 public int read(int r)throws IOException{} 此方法從InputStream讀取指定的數據字節,並返回一個int值。 返回數據的下一個位元組,如果它是檔的末尾,則返回-1
4 public int read(byte[] r) throws IOException{} 此方法將輸入流中的r.length個位元組讀入數組。返回讀取的總位元組數。 如果它到達檔的結尾,則返回-1
5 public int available() throws IOException{} 給出可以從此檔輸入流中讀取的位元組數。 返回一個int值。

還有其他重要的輸入流可用,有關更多詳細資訊,請參閱以下鏈接 -

3.2. FileOutputStream

FileOutputStream用於創建檔並將數據寫入檔。 如果檔尚不存在,則會在打開檔以進行輸出之前創建該檔。

這裏有兩個構造函數,可用於創建FileOutputStream對象。

以下構造函數將檔案名作為字串來創建輸入流對象以寫入檔 -

OutputStream f = new FileOutputStream("D:/java/hello.txt")

下麵的構造函數接受一個檔對象來創建一個輸出流對象來寫入該檔。 首先,使用File()方法創建一個檔對象,如下所示 -

File f = new File("D:/java/hello.txt");
OutputStream f = new FileOutputStream(f);

當創建了OutputStream對象,就使用它的一些輔助方法來寫入流或在流上執行其他操作。

編號 方法 描述
1 public void close() throws IOException{} 此方法關閉檔輸出流,釋放與該檔關聯的所有系統資源。拋出IOException
2 protected void finalize()throws IOException {} 此方法清除與檔的連接,確保在沒有對此流的引用時調用此檔輸出流的close()方法。拋出IOException
3 public void write(int w)throws IOException{} 此方法將指定的位元組寫入輸出流。
4 public void write(byte[] w) 將長度為w.length的位元組從位元組數組寫入OutputStream

還有其他重要的輸出流,有關更多詳細資訊,請參閱以下鏈接 -

示例

以下是演示如何使用InputStreamOutputStream類對象的示例 -

import java.io.*;
public class fileStreamTest {

   public static void main(String args[]) {

      try {
         byte bWrite [] = {11,21,3,40,5};
         OutputStream os = new FileOutputStream("D:/test.txt");
         for(int x = 0; x < bWrite.length ; x++) {
            os.write( bWrite[x] );   // writes the bytes
         }
         os.close();

         InputStream is = new FileInputStream("D:/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並將以二進位格式寫入給定的數字數據,同樣也會在螢幕上輸出。

4. 檔導航和I/O

可通過其他幾個類來瞭解檔導航和I/O的基礎知識。如下 -

4.1. 目錄操作

目錄是一個檔,它可以包含其他檔和目錄的列表。 使用File對象創建目錄,列出目錄中可用的檔。 有關完整的詳細資訊,請查看在File對象上調用的所有方法的列表以及與目錄相關的內容。

4.1.1. 創建目錄

有兩種File類的方法,可用於創建目錄 -

  • mkdir()方法創建一個目錄,創建成功時返回true,失敗時返回false。 失敗表示File對象中指定的路徑已存在,或者由於整個路徑尚不存在或許可權問題而無法創建目錄。
  • mkdirs()方法創建目錄和目錄的所有上級目錄。

以下示例創建一個目錄:D:/tmp/user/java/bin -

示例

import java.io.File;
public class CreateDir {

   public static void main(String args[]) {
      String dirname = "D:/tmp/user/java/bin";
      File d = new File(dirname);

      // 創建目錄及父級目錄

      d.mkdirs();
   }
}

編譯並執行上面的代碼來創建目錄:D:/tmp/user/java/bin

注 - Java會根據約定自動處理UNIX和Windows上的路徑分隔符號。如果在Windows版本的Java上使用正斜杠(/),則路徑仍將正確解析。

4.1.2. 列出目錄

可以使用File對象的list()方法列出目錄中可用的所有檔和目錄,如下所示 -

import java.io.File;
public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;

      try {
         // 創建一個File對象
         file = new File("D:/software");

         // 檔和目錄的數組

         paths = file.list();

         // 對於路徑數組中的名稱
         for(String path:paths) {
            // 列印檔案名和目錄名

            System.out.println(path);
         }
      } catch (Exception e) {
         // if any error occurs
         e.printStackTrace();
      }
   }
}

執行上面代碼,它將根據D:/software目錄中目錄和文件產生以下結果 -

apache-maven-3.5.4
apache-tomcat-9.0.14
Aptana_Studio
eclipse
EditPlusPortable
javajars
kafka_2.11-2.0.0
mysql-5.7.23-winx64
Navicat Premium 11
php-cs-fixer.phar
spring-2.0.5.RELEASE
... ...

上一篇: Java方法 下一篇: Java快速入門