CodeGym /Java Blog /Toto sisi /Java 中的輸入/輸出。FileInputStream、FileOutputStream 和 BufferedI...
John Squirrels
等級 41
San Francisco

Java 中的輸入/輸出。FileInputStream、FileOutputStream 和 BufferedInputStream 類

在 Toto sisi 群組發布
“嗨!在今天的課程中,我們將繼續討論 Java 中的輸入和輸出流 ( Java I/O )。這不是關於該主題的第一課,當然也不會是最後一課 :) Java 中的輸入/輸出。 FileInputStream、FileOutputStream 和 BufferedInputStream 類 - 1因為它碰巧,Java 語言提供了很多處理 I/O 的方法。有相當多的類實現了這個功能,所以我們把它們分成幾節課——所以你不會從一開始就感到困惑 :) 過去課程,我們談到了BufferedReader,以及抽像類InputStreamOutputStream幾個後代。今天我們將考慮 3 個新類:FileInputStream FileOutputStream和 BufferedInputStream

文件輸出流類

該類的主要目的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 CodeGym — The best site for would-be programmers!"; 

       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 CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
兩種情況下的結果都是一樣的。 我們可以打開我們的文件並在那裡看到以下內容:

Hi! Welcome to CodeGym — The best site for would-be programmers!
但這裡有一個細微差別。嘗試連續多次運行上述示例中的代碼。然後查看文件並回答這個問題:它有多少行?只有一個。但是你多次運行代碼。事實證明,數據每次都被覆蓋——舊的被新的取代。如果這不適合我們並且我們需要按順序寫入文件,我們該怎麼辦?如果我們想連續三次將問候語寫入文件怎麼辦?這一切都非常簡單。由於語言無法知道我們在每種情況下需要什麼行為,FileOutputStream構造函數可以採用一個額外的參數——boolean append. 如果它的值為真,數據將被寫入文件的末尾。如果為 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 CodeGym — The best site for would-be programmers!\r\n"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
文件內容:

Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers!
現在不一樣了!在使用 I/O 類時不要忘記這個特性。曾經有一段時間,我在任務上花費了數小時,絞盡腦汁數小時,試圖了解我的數據是如何從文件中消失的:)當然,就像其他 I/O 類一樣,不要忘記使用該close()方法釋放資源。

文件輸入流類

FileInputStream相反的目的——從文件中讀取字節。正如FileOutputStreaminherits一樣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 中的輸入/輸出。 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類以及它與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 毫秒內完成了它。如您所見,緩衝流優化了工作,將其減半!:) 我們將繼續研究 I/O 課程——待會見!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION