j2se學習中的一些零碎知識點7
1、 關於流的概念:流根據方向可以分為:輸入流和輸出流。(註意,輸入和輸入是相對於內存而言的,從內存中出來叫做輸出,到內存中就是輸入。輸入流有叫做InputStream,輸出流有叫做OutputStream。輸入有叫做“讀Read”,輸出還叫做“寫Write”。)
- 流根據讀取數據的方式可以分為:字節流和字符流,字節流是按照字節的方式讀取,字符流是按照字符的方式讀取,一次讀取2個字節,java語言中一個字符占2個字節。(字節流適合讀取視頻、聲音、圖片等二進制文件;字符流讀取純文本文件。)
- Java語言中所有的字節流都以Stream結尾,所有的字符流都含有Reader或者Writer。
- 需要掌握的16個流:(java.io)
FileInputStream/FileOutputStream/FileReader/FileWriter;
BufferedReader/BufferedWriter/BufferedInputStream/BufferedOutputStream;
DataInputStream/DataOutputStream;
ObjectInputStream/ObjectOutputStream;
InputStreamReader/OutputStreamWriter;(轉換流:將字節流轉換成字符流)
PrintWriter/PrintStream(標準的輸出流【默認輸出到控制臺】);
2、java語言中的流分為:四大家族(InputStream、OutputStream、Writer、Reader)
- InputStream、OutputStream的繼承結構圖
:
- Reader和Writer的繼承結構圖:
3、 java.io.FileInputStream;文件字節輸入流:
- 可以使用構造器FileInputStream(String name)傳遞文件路徑(相對路徑或者絕對路徑)參數創建FileInputStream對象:(需要註意的是,在windows操作系統中,表示文件路徑可以使用“/”或者是“\”,但是“\”在java字符串中有特殊的含義,需要使用“\\”轉義字符表示反斜杠;在linux系統中采用正斜杠“/”。)
- 使用read()方法來讀取字節(一次讀取一個字節,讀取至末尾後,再讀取會返回-1):(需要註意,讀取返回值為int類型,為ascll編碼值,讀取效率低):
- 使用read(byte[] b)方法來讀取多個字節(字節數有指定傳遞的參數b指定,返回值為讀取的總字節個數):
- 構造器String(byte[] bytes)方法可以將byte[]數組中的所有字節解碼轉換成字符串:
- 構造器String(byte[] bytes, int offset, int length) 可以將byte[]數組中的指定的子數組中的字節解碼成字符串:
- close()方法用以關閉流(流開啟後必須關閉),在finally語句塊中使用,需要判斷該流是否為null再進行關閉:
- available()方法返回流中剩余的估計的字節數:
- skip(long n)方法表示在這個輸入流中跳過並拋棄n個字節:
4、 java.io.FileOutputStream;文件字節輸出流:(推薦結束前為了保證數據全部寫入硬盤,進行刷新操作)
- 構造器FileOuptStream(String name)方法創建FileOutputStream對象,此構造器會將源文件中的內容覆蓋,謹慎使用。(如果文件不存在則自動創建)
- 構造器FileOuptStream(String name, boolean append)方法表示創建FileOutputStream對象,並在寫入數據到文件中時是以追加的方式寫入:
- String類的getBytes()方法:把字符串編碼成指定的的字節序列,並存儲在新創建的一個字節數組中:
- 將字節數組中的所有字節寫入到文件輸出流中:
- Flushable接口中的flush()方法:強制刷新輸出流,以此保證將所有的緩存中的字節/字符全部寫入流中:
- 將字節數組中的子數組中的指定字節寫入到文件輸出流中:
5、java.io.FileReader:文件字符輸入流(需要註意,字節讀取文本文件可能會導致亂碼,因為byte類型為1字節;所以文本文件盡量選擇使用字符流,因為char類型為2字節)
- 構造器FileReader(String fileName)方法和FileInputStream類似。
- 抽象類Reader中的read(char[] cbuf)方法:讀取字符數組中的所有字符序列,每次方法調用返回讀取的字符序列個數;讀取至末尾後,該方法再次讀取會返回-1。
- 類InputStreamReader中的read(char[] cbuf, int offset, int length)方法:讀取字符數組中的部分字符序列,每次方法調用返回讀取的字符序列個數;讀取至末尾後,該方法再此讀取會返回-1。
6、java.io.FileWriter:文件字符輸出流
- 構造器FileWriter(String fileName)方法創建文件字符輸出流,字符序列寫入文件時覆蓋文件內容。
- 構造器FileWriter(String fileName, boolean append)方法創建文件字符輸出流,字符序列寫入文件時追加文件內容。
- 類OutputStreamWriter中的write(String str, int off, int len)方法:寫入指定字符串的一部分。
- 類OutputStreamWriter中的write(char[] cbuf, int off, int len)方法:寫入指定字符數組的一部分。
7、java.io.BufferedReader:帶有緩沖區的字符輸入流(將文件字符輸入流包裝成帶有緩沖區的的字符輸入流)
- 構造器創建一個BufferedReader對象(處理流或者說是包裝),參數為一個Reader類型的對象,可以為FileReader對象。(需要註意的是,關閉只需要關閉最外層的包裝流即可。)
- readLine()方法中從流中讀取一行數據:(如果返回的對象為null,則表示讀取已結束。行尾不帶換行符。)
- java.io.InputStreamReader中的構造器InputStreamReader(InputStream in)方法可以將InputStream字節輸入流轉換成InputSreamReader轉換流。 (InputStreamReader類繼承至Reader抽象類)
- System.in返回的是一個標準的輸入流,默認接收鍵盤輸入:
8、java.io.BufferedWriter:帶有緩沖區的字符輸出流:
- 構造器BufferedWriter(Writer out)方法和BufferedWriter構造器方法類似:
- newLine()方法向輸出流中寫入一個行分隔符:
- write(char [] cbuf, int off, int len)方法向輸出流中寫入字符數組中的一部分:
- write(String s, int off, int len)方法像輸出流中寫入字符串中的一部分:
9、java.io.DataOutputStream:數據字節輸出流(可以將內存中的 int i = 10;寫入到硬盤文件中,寫進入的不是字符串,寫進入的是二進制數據(帶類型))
- 構造器DataOutputStream(OutputStream out)方法創建一個新的數據輸出流將內存中數據寫入到指定的底層輸出流中:
- 將內存中的java數據寫入到底層輸出流中:(寫入的文件為二進制文件。)
10、java.io.DataInputStream:數據字節輸入流(需要註意的是,要使用該流讀取數據,必須提前知道該文件中數據的存儲格式和順序。讀取的順序必須和寫入的順序相同。)
- 讀取數據字節輸入流中的數據值:
11、java.io.PrintStream:標準的輸出流,默認打印到控制臺,以字節方式。(PrintStream ps = System.out;)
- 可以改變輸出方向:重新指定標準輸出流(可以將打印輸出到指定的文件中)
- 構造器PringStream方法創建新的打印流(需要傳遞OutputStream參數對象)
12、java.io.ObjectOutputStream:序列化java對象到硬盤。(Serial)(需要序列化的java對象,對象類需要實現Serializable接口)
- 構造器ObjectOutputStream(OutputStream out)方法創建序列化流(需要傳入一個字節輸出流對象):(文件中寫進入的數據為二進制文件)
- java.io.Serializable接口是一個“可序列化的”標識接口,該接口沒有任何方法。(與之類似的接口還有:java.lang.Cloneable接口【可克隆的】)
- 標識接口的作用:起到標識的作用,JVM如果看到該對象實現了某個標識接口,給予特殊的待遇。(給類實現Serializable接口,在編譯時編譯器會給該類添加一個long serialVersionUID(static final)序列化版本號屬性,在序列化後的硬盤文件中記錄該序列化版本號,以此和反序列化時編譯後的對象類中的序列化版本號做對比。)
- writeObject(Object obj)方法將指定的對象寫入到序列化流中:
13、java.io.ObjectInputStream:將硬盤中的數據“反序列化”到JVM內存中。(DeSerial)(在反序列化的過程中,序列化時創建的對象類的.class文件將會被會被重新使用。)
- ObjectInputStream類構造器與ObjectOutputStream類構造器相似:
- 從反序列化流中讀取一個對象:
14、序列化版本號:如果一個類實現Serializable接口,(所謂的特殊待遇)會給該類添加一個long serialVersionUID(static final)屬性。(如果將該對象類重新編譯(重新生成對象類的.class文件),序列化版本號屬性serialVersionUID可能會發生變化【如果類中的代碼發生改變】。)
- 序列化版本號不對應,反序列化時可能會出現java.io.InvalidClassException異常:
- 一般情況下,不讓系統自動生成,自己在類中手動提供一個序列化版本號。
- 如果不想讓類中屬性參加序列化,需要使用transient關鍵字修飾。
15、java.io.File類:File類與流無關,不能通過該類完成文件的讀和寫。(File是文件和目錄路徑名的抽象表示形式。即代表的是硬盤中的文件或者目錄)
- 構造器File(String pathname)方法通過將給定的路徑名字符串來創建File對象:
- exists()方法檢測File對象中給定的絕對路徑中是否存在對應的文件或者目錄:
- mkdir()方法或者createNewFile()方法是指在當前路徑中創建目錄或者文件:(使用exists()方法進行檢測)
- mkdirs()方法是指創建多重目錄(如果使用exists()方法進行檢測目錄不存在。)
- 判斷File對象表示的文件是否可執行、可讀、可寫:
- getAbsolutePath()方法獲取絕對路徑:
- getParent()方法獲取文件或者是目錄中的父路徑:(或者為null,如果不存在父目錄)
- lastModified()方法獲取文件最後一次修改時間:
- length()方法返回文件的長度(字節數):
- listFiles()方法返回絕對路徑(絕對路徑為目錄的情況)下的所有File數組(包括文件和目錄):
j2se學習中的一些零碎知識點7