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