Java的IO流是實現輸入/輸出的基礎,它可以方便的實現數據的輸入/輸出操作。
Java中把不同的輸入/輸出源(鍵盤、文件、網絡連接等)抽象為“流”(stream),通過流的方式可以使用相同的方式來訪問不同的輸入/輸出源。
stream是從起源(source)到接收(sink)的有序數據。
再java.io包中,大概分為以下四種:
- 基于字節:InputStream、OutputStream
- 基于字符:Write、Reader
- 基于磁盤操作:File
- 基于網絡傳輸:Socket
輸入流:只能從中讀取數據。
輸出流:只能向其寫入數據。
文件的編碼
gbk編碼:中文占用2個字節,英文占用1個字節。
utf-8編碼:中文占用3個字節,英文占用1個字節。
utf-16be編碼:中文占用2個字節,英文占用2個字節。
Java是雙字節編碼,utf-16be。
1、字節流
輸入流基本方法
int read()
int read(byte[] buf)
int read(byte[] buf, int start, int size)
read()
返回 -1 就表示讀到結尾。
int available() // 返回當前可讀取的輸入字節數
void mark(int numBytes) // 在輸入流的當前點放置標記,在讀取numBytes個字節之前保持有效
boolean markSupported() // 判斷此輸入流是否支持 mark() 操作
void reset() // 將輸入指針重新改為原來設置的標記
long skip(long numBytes) // 忽略(即跳過)numBytes個輸入字節,返回實際忽略的字節數
void close() // 關閉輸入流
輸出流基本方法
void write(int b) // 寫出一個byte到流
void write(byte[] buf)
void write(byte[] buf, int start, int size)
void flush()
void close()
2、字符流
int read()
int read(char[] cbuf)
int read(char[] cbuf, int off, int len)
read()
返回 -1 就表示讀到結尾。
void mark(int numBytes) // 在輸入流的當前點放置標記,在讀取numBytes個字符之前保持有效
boolean markSupported() // 判斷此輸入流是否支持 mark() 操作
void reset() // 將輸入指針重新改為原來設置的標記
long skip(long numBytes) // 忽略(即跳過)numBytes個輸入字符,返回實際忽略的字符數
boolean ready() // 如果下一個輸入請求不等待就返回 true,否則返回 false
void close() // 關閉輸入流
void write(int c)
void write(char[] cbuf)
void write(char[] cbuf, int off, int len)
void write(String str)
void write(String str, int off, int len)
Writer append(char ch)
Writer append(CharSequence chars)
Writer append(CharSequence chars, int begin, int end)
void flush()
void close()
3、 處理字節或二進制對象(圖片、視屏等媒體文件):
FileInputStream 具體實現了在文件上讀取數據
FileOutputStream 實現了向文件中寫出byte數據的方法
4、讀寫二進制數據
DataOutputStream
、DataInputStream
是對"流"功能的擴展,可以更加方便的讀取int
、long
、short
、float
、double
、char
、byte
、boolean
類型數據。
DataInputStream
int readInt()
double readDouble()
long readLong()
short readShort()
float readFloat()
char readChar()
byte readByte()
boolean readBoolean()
DataOutputStream
writeInt(int val)
writeDouble(double val)
writeLong(long val)
writeShort(short val)
writeFloat(float val)
writeChar(char val)
writeByte(byte val)
writeBoolean(boolean val)
5、帶緩存的流:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
增加緩沖功能后,要使用 flush()
才可以將緩沖區的數據寫入實際的物理節點。
這四個流類為IO提供了帶緩沖區的操作,一般打開文件進行寫入 或讀取操作時,都會加上緩沖,這種流模式提高了IO的性能。
從應用程序中把輸入放入文件,相當于將一缸水倒入到另一個缸中:
FileOutputStream--->write()方法相當于一滴一滴地把水“轉移”過去
DataOutputStream-->writeXxx()方法會方便一些,相當于一瓢一瓢把水“轉移”過去
BufferedOutputStream--->write方法更方便,相當于一飄一瓢先放入桶中,再從桶中倒入到另一個缸中,性能提高了
6、轉換流
InputStreamReader
將字節輸入流轉換成字符輸入流
OutputStreamWriter
將字節輸出流轉換成字符輸出流
7、推回輸入流
PushbackInputStream
、PushbackReader
void unread(byte[]/char[] buf)
void unread(byte[]/char[] b, int off, int len)
void unread(int b)
8、重定向標準輸入輸出流
Java的標準輸入/輸出流分別通過System.in
和System.out
來代表。
在 System 類里,提供了三個重定向標準輸入/輸出的方法:
static void setErr(PrintStream err)
static void setIn(PrintStream in)
static void setOut(PrintStream out)
RandomAccessFile類 (隨機訪問文件)
RandomAccessFile
可以自由的訪問文件的任意位置,支持“隨機訪問”的方式。
該類僅限于操作文件,不能訪問其他IO設備,如網絡、內存映像等。
RandomAccessFile(String filename, String access)
access :文件的訪問類型。r
、rw
、rws
、rwd
int read()
void write()
long getFilePointer() // 返回文件記錄指針的當前位置
void seek(long pos) // 將文件記錄指針定位到 pos 位置
RandomAccessFile 不能向文件的指定位置插入內容,如果直接文件記錄指針移動到中間某位置后開始輸入,則新輸出的內容會覆蓋文件中原有的內容。
如果需要向指定位置插入內容,需要先把插入點后面的內容輸入緩沖區,等把需要插入的數據寫入文件后,再將緩沖區的內容追加到文件后面。
Console類
JDK6添加的類,用來從控制臺讀寫。
Console對象通過System.console()
獲得。
readLine()
printf()
readPassword() // 讀取密碼,不回顯鍵盤的輸入
自動關閉資源的 try 語句
在不需要資源時,顯式地調用了close()
來關閉資源。代碼中廣泛的使用這種方法。
JDK7 開始,Java新增了一種功能,自動化關閉資源。這種功能的基礎是一種新形式的 try 語句,叫做 try-with-resources
,有時候稱為自動資源管理。
try-with-resources
的主要優勢在于避免了當不需要資源時,忘記關閉資源的情況。
忘記關閉資源可能會導致內存泄露,并引起其他問題。
為了保證 try 語句可以正常關閉資源,這些資源實現類必須實現 AutoCloseable 或 Closeable 接口,實現這兩個接口就必須實現 close() 方法。
其語法形式:
// 聲明、初始化了兩個可關閉的資源,try語句會自動關閉這兩個資源
try (BufferedReader br = new BufferedReader(new FileReader("Test.java"));
PrintStream ps = new PrintStream(new FileOutputStream("a.txt"))) {
System.out.println(br.readLine());
ps.println("輸出內容");
}
try 語句塊可管理多個資源,用;
隔開。
自動關閉資源的 try 語句后也可以帶多個 catch 塊和一個 finally 塊。
Java7 幾乎把所有的“資源類”(包括文件IO的各種類、JDBC編程的類、網絡鏈接等)進行了改寫,改寫后資源類都實現了 AutoCloseable 或 Closeable 接口。