Java Basics Part 18/20 - Files and I/O

Java Basics Part 18/20 - Files and I/O

目錄


java.io 包幾乎包含了操作 I/O 所需要的所有類。所有的這些流都代表了一個輸入和一個輸出。java.io 包支持很多的數據類型,包括原始數據類型,對象,本地化字符等等。


Streams

可以認爲流(Streams)就是一串數據序列。有兩種形式:

  • 輸入流:輸入流用來從 source 中讀取數據。
  • 輸出流:輸出流用來往 destination 中寫入數據。

streams

Java 爲文件和網絡提供了功能非常強大和靈活的支持。但是這裏只介紹基本的流和 I/O。下面逐一介紹最常用的一些流。


Byte Streams

Java 的字節流是用來操作 8-bit 字節的輸入輸出的。雖然有很多類都和字節流有關係,但是最常用的兩個類是 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("input.txt");
         out = new FileOutputStream("output.txt");

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

現在我們在 input.txt 文件中有以下內容:

This is test for copy file.

按照如下步驟編譯然後運行,會得到一個 output.txt 文件,它的內容和 input.txt 是一樣的。

$javac CopyFile.java
$java CopyFile

Character Streams

Java 的字節流用來操作 8-bit 字節的輸入和輸出的,而 Java 的字符流(Character Streams)用來操作 16-bit 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("input.txt");
         out = new FileWriter("output.txt");

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

編譯運行與上一節相同。


Standard Streams

所有的編程語言都提供了標準 I/O,也就是用戶可以從鍵盤讀取輸入並且把輸出顯示到屏幕上。如果接觸過 C/C++ 的話,那麼一定知道三個標準設備 STDIN, STDOUT 和 STDERR。與此相似,Java 也提供瞭如下三個標準流:

  • Standard Input: 用來爲程序提供數據,通常鍵盤用作標準輸入流,Java 中用 System.in 表示。
  • Standard Output: 用來爲程序輸出數據,通常電腦屏幕用作標準輸出流,Java 中用 System.out 表示。
  • Standard Error: 用來爲程序輸出錯誤數據,通常電腦屏幕用作標準錯誤流,Java 中用 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();
         }
      }
   }
}

編譯運行:

$javac ReadConsole.java
$java ReadConsole
Enter characters, 'q' to quit.
1
1
e
e
q
q

Reading and Writing Files

如前所述,流是一串數據序列。InputStream 用來從 source 中讀取數據, OutputStream 往 destination 中寫入數據。

下圖是 Input 和 Output 流的類結構圖。

file_io

兩個重要的流是 FileInputStreamFileOutputStream,下面就來介紹下這兩個類。


FileInputStream

這個流用來從文件中讀取數據。這個類有很多的構造器。

如下構造器接收一個字符串類型的形參作爲文件名,並且基於這個文件創建一個輸入流:

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

如下這個構造器結構一個 File 對象,基於這個文件創建一個輸入流,首先要使用 File() 創建一個 file 對象:

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

一旦持有了 InputStream,那麼就有很多操作 流 的方法可以使用了。

SN Methods with Description
1 public void close() throws IOException{}: 關閉資源。
2 protected void finalize()throws IOException {}:清除 文件連接。
3 public int read()throws IOException{}:讀取 1 個字節的數據。
4 public int read(byte[] r) throws IOException{}:讀取 r.length 個字節的數據到數組裏。
5 public int available() throws IOException{}:返回文件輸入流中還有多少字節數據可讀。

還有其他一些很重要的輸入流,詳情請點擊:


FileOutputStream

FileOutputStream 創建一個可以寫入數據的文件。如果文件不存在,會創建一個。

下面是它的兩個構造器。

第一個構造器接收一個字符串類型的文件名稱做參數,基於這個文件創建一個輸出流:

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

第二個構造器接收一個文件對象做參數,然後寫入這個文件對象指向的文件:

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

一旦持有了 OutputStream,那麼就有很多操作流的方法可以使用了。

SN Methods with Description
1 public void close() throws IOException{}: 關閉流
2 protected void finalize()throws IOException {}:確保清除文件鏈接
3 public void write()throws IOException{}:寫入一個字節
4 public void write(byte[] w):寫入整個字節數組

還有其他的輸出流可供使用,詳情請點擊:

舉例:
演示 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("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 文件,然後以二進制格式寫入一串給定的數字。相同的內容會出現在 stdout 上。


File Navigation and I/O

還有一些其他的操作 File 的類可以學習:


Directories in Java

可以使用 File 對象來 創建目錄列出目錄中的文件 等等。


Creating Directories

有兩個很有用的 File 工具方法,都可以用來創建目錄:

  • mkdir():返回 boolean。如果 路經 存在,那麼返回失敗。
  • 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);
      // Create directory now.
      d.mkdirs();
  }
}

注意路徑分隔符,Unix 和 Windows 都可以處理 “/”


Listing Directories

可以使用 File 對象的 list() 方法來列出文件夾中的所有文件:

import java.io.File;

public class ReadDir {
   public static void main(String[] args) {

      File file = null;
      String[] paths;

      try{      
         // create new file object
         file = new File("/tmp");

         // array of files and directory
         paths = file.list();

         // for each name in the path array
         for(String path:paths)
         {
            // prints filename and directory name
            System.out.println(path);
         }
      }catch(Exception e){
         // if any error occurs
         e.printStackTrace();
      }
   }
}

這個程序會列出 /tmp 文件夾中的所有目錄和文件:

test1.txt
test2.txt
ReadDir.java
ReadDir.class
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章