JavaRush /Java Blog /Random-TW /Java 中的 I/O。類別 FileInputStream、FileOutputStream、BufferedI...

Java 中的 I/O。類別 FileInputStream、FileOutputStream、BufferedInputStream

在 Random-TW 群組發布
你好!在今天的講座中,我們將繼續討論 Java 中的輸入和輸出流,簡稱Java I/O(「輸入輸出」)。這不是關於這個主題的第一場講座,也不會是最後一場:) 碰巧 Java 作為一種語言提供了許多處理輸入/輸出的機會。有相當多的類別實現了這個功能,所以我們把它們分成幾個講座,這樣你一開始就不會感到困惑:)在之前的講座中,我們接觸過Java 中的 I/O。 類別 FileInputStream、FileOutputStream、BufferedInputStream - 1BufferedReader 以及抽象類別InputStream 和 OutputStream以及幾個後人。今天我們將看看 3 個新類別:FileInputStreamFileOutputStreamBufferedInputStream

檔案輸出流類

FileOutputStream類別的主要用途是將位元組寫入檔案。 沒什麼複雜的:) FileOutputStream是抽象OutputStream類別的實作之一。在建構函式中,此類的物件採用目標檔案(需要寫入位元組)的路徑或該類別的物件File。讓我們來看這兩個例子:
public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
建立物件時,File我們在建構函式中指定了該物件所在的路徑。無需提前建立:如果不存在,程式將自行建立。您可以不建立額外的對象,而只需傳遞帶有地址的字串:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
兩種情況的結果是相同的。我們可以打開我們的文件並看到:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
然而,這裡有一個警告。嘗試連續運行上面範例中的程式碼幾次,然後查看該檔案並回答問題:您看到其中寫了多少行?只有一個。但您多次運行該程式碼。然而,事實證明,數據每次都被覆蓋,替換舊的。如果我們對此不滿意並需要順序記錄怎麼辦?如果我們想連續三次將問候語寫入檔案怎麼辦?這裡一切都很簡單。由於語言本身無法知道我們在每種情況下需要什麼樣的行為,因此FileOutputStream您可以向建構函式傳遞一個附加參數 - boolean append。如果其值為true,資料將寫入檔案結尾。如果為false(預設值為false),舊資料將被刪除並寫入新資料。讓我們測試並運行修改後的程式碼三次:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
文件中的結果:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
另一件事!使用 I/O 類別時請記住此功能。有一次,我不得不花幾個小時來處理任務,以了解我的舊數據從文件中去了哪裡:)當然,與其他 I/O 類的情況一樣,不要忘記通過close().

檔案輸入流類

該類別具有FileInputStream相反的目的 - 從文件中讀取位元組。就像FileOutputStream繼承一樣OutputStream,這類派生自抽象類別InputStream。讓我們在文字「test.txt 」中寫入幾行文字 :

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
Java 中的 I/O。 類別 FileInputStream、FileOutputStream、BufferedInputStream - 2 這是使用以下方法從文件讀取資料的實作FileInputStream
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
我們從文件中讀取一個字節,將讀取的位元組轉換為字元並將其輸出到控制台。這是控制台中的結果:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

BufferedInputStream 類

我認為,鑑於之前講座中的知識,您可以輕鬆說出為什麼需要該類別BufferedInputStream以及它具有哪些優勢FileInputStream:)我們已經遇到過緩衝流,因此在繼續閱讀之前嘗試猜測(或記住):) 緩衝流主要需要優化I/O。 存取資料來源(例如從檔案中讀取)是一項效能密集型操作。並且每次存取文件讀取一個位元組是一種浪費。因此,BufferedInputStream它不是一次讀取一個字節,而是分塊讀取數據,並將它們暫時儲存在特殊的緩衝區中。這使我們能夠透過減少對文件的存取次數來優化程式的操作。讓我們看看它是什麼樣子的:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
這裡我們創建了一個物件BufferedInputStream。它接受一個物件或其任何後繼者作為輸入InputStream,因此前一個FileInputStream就可以了。它將緩衝區大小(以位元組為單位)作為附加參數。現在,多虧了這一點,數據將從文件中讀取,而不是一次一個字節,而是一次 200 個!想像一下我們減少了多少文件訪問次數。FileInputStream為了比較效能,您可以使用一些大小為幾兆位元組的大型文字文件,並使用和來比較讀取它並將其輸出到控制台所需的時間(以毫秒為單位)BufferedInputStream。以下是兩個程式碼範例:
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
在我的電腦上讀取 1.5 MB 檔案時,FileInputStream它在大約 3500 毫秒內完成了工作,但在這裡BufferedInputStream它在大約 1700 毫秒內完成了工作。正如您所看到的,緩衝流將程式的效能優化了 2 倍!:) 我們將繼續學習 I/O 課程 - 很快再見!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION