簡體   English   中英

如何選擇將字符串寫入文件所需的主要Java IO類?

[英]How do I choose which of the main Java IO classes I need to write strings to a file?

IO包中有許多不同的類,有些似乎只有差異。 如果要將一些字符串寫入文本文件,並將其讀取以供以后使用。 你會為這兩個目的使用哪些課程?為什么?

  • 的BufferedInputStream
  • 的BufferedOutputStream
  • 但是BufferedWriter
  • 的BufferedReader
  • DataInputStream類
  • DataOutputStream類
  • 的FileInputStream
  • FileOutputStream中
  • 的FileReader
  • 的FileWriter
  • InputStreamReader中
  • OutputStreamReader
  • 讀者
  • 作家

這一切都取決於你想做什么。

輸出流

如果要寫字節數據 ,可以使用OutputStream一些子類,用於在具體子類定義的目標中寫入字節。

例如, FileOutputStream用於逐字節(或字節串)以文件形式寫入數據。

BufferedOutputStreamFileOutputStream的優化擴展,用於寫入字節塊以最小化磁盤操作數。 因此,當您調用write時,實際上它可能會或可能不會寫入文件 - 取決於緩沖區的狀態是否已滿。 如果緩沖區達到最大容量,則立即將所有字節刷新到文件。

ByteArrayOutputStream僅使用內存塊作為目標而不是文件。 當前流內容是通過toByteArray()方法獲得的(為什么你需要這樣的流將在后面解釋)。

ObjectOutputStream用於在由底層OutputStream定義的某個目標中寫入對象(類實例)。 例如, ObjectOutputStream(FileOutputStream)將在文件中寫入對象,而ObjectOutputStream(ByteArrayOutputStream)將在內存中寫入對象。 最后一個選項允許您在字節緩沖區(字節數組)中序列化對象,然后可以通過網絡將其發送到某處。

請注意,您想通過ObjectOutputStream在某處寫入的任何對象都必須實現Serializable接口。 由於object可能包含對另一個對象的引用,因此可以從要序列化的對象訪問的所有對象也必須實現Serializable接口作為序列化 ,默認情況下,是對象完整圖形的寫入過程 - 假設您沒有使用transient關鍵字從序列化中排除類字段,或者您沒有在對象的類中定義一個特殊方法writeObject/readObject來覆蓋默認的序列化行為。 這些方法旨在實現自定義序列化,即您可以自己定義如何在ObjectOutputStream/ObjectInputStream編寫/讀取類字段。 假設您要為其實現自定義序列化的A類包含B類對象。 而不是將對象b寫為完整的圖,而不是調用oos.writeObject(b) ,其中oos是在類A中實現的writeObject方法的參數,您將僅在流中寫入類B一些字段,例如oos.writeBoolean(b.isEnabled)oos.writeInt(b.value) 只要對象b不是通過oos.writeObject(b)編寫的,它就不必實現Serializable接口。 有關詳細信息,請參閱Serializable文檔。

DataOutputStream用於編寫booleancharintlongfloatdouble等基元 因為任何對象都可以分解為基元,例如class A { int i = 0; B b = new B();} class A { int i = 0; B b = new B();}class B {double d = 0.0;}可以簡單地寫成int a, double d ,你可以使用DataOutputStream以壓縮方式序列化對象,而不像序列化那樣寫入更多數據,例如類路徑,類版本,...因此ClassLoader可以在運行時標識給定的類,實例化此類並最終將數據加載到此空對象。 請注意,以這種方式通過它的名稱+初始化對象實例化類比自己實例化類並且從“原始” DataOutputStream自己初始化它的字段要慢得多(這就是為什么OS Android更喜歡自定義Parcelable接口而不是標准序列化,這可以作為寫入/讀取DataOutputStream/DataInputStream )。

如果你想寫字符串數據 ,你可以使用OutputStreamWriter更高級別的輸出流,它在OutputStream定義的目標中寫入字符/字符串(如果在文件中寫入,你將傳遞FileOutputStream ,如果在內存中寫入你將通過ByteArrayOutputStream )。

FileWriterOutputStreamWriter的擴展,專為文件寫入而設計。

BufferedWriter工作方式相同BufferedOutputStream除了它是專為與字符串和字符的工作。

CharArrayWriterByteArrayOutputStream工作方式相同,只是字符存儲在char[] ,而char[]是通過調用getCharArray()獲得的。

StringWriter類似於CharArrayWriter除了它允許您編寫存儲在StringBuffer中的字符串,該字符串是通過調用getBuffer()獲得的。

PrintWriter允許您在OutputStream定義的指定目標中編寫格式化字符串(此編寫器旨在OutputStream日志記錄)。

輸入流

相同的概念應用於與上述給定輸出流(寫入器)相關聯的輸入流(讀取器)。

  • 讀取器和InputStream用於輸入,而Writers和OutputStream用於輸出。
  • 讀者和寫者用於文本(帶字符集),而InputStreams和OutputStream用於二進制數據(如圖像)。
  • 緩沖有助於提高性能,因為讀取和寫入是批處理的,而不是每次使用任何方法時都進行系統調用。
  • 如果名稱中包含“文件”,則用於文件。

因此,對於您希望將文本寫入文件的特定情況,最明顯的候選者是FileWriter:

Writer out = new FileWriter(
    new File("foo.txt")
);

如果想要對它進行許多小寫操作需要更好的性能,可以將它包裝在緩沖區中:

Writer out = new BufferedWriter(
    new FileWriter(
        new File("foo.txt")
    )
);

FileWriter在編寫文本時采用默認字符編碼。 如果要選擇編碼,或確保它在所有平台上都是一致的,可以從OutputStream創建編寫器,明確指定編碼:

Writer out = new BufferedWriter(
    new OutputStreamWriter(
        new FileOutputStream(
            new File("foo.txt")
        ), "UTF-8"
    )
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM