Java学习笔记-7.Java IO流
一、輸入/輸出流
1.流:不同類型的輸入、輸出源??? 數(shù)據(jù)流:輸入或輸出的數(shù)據(jù)
?? Java數(shù)據(jù)流的所有接口和類都是在java.io包中定義的,因此應(yīng)在程序開頭加入
?? import java.io.*
2.流的分類:
? (1)從流的流動(dòng)方向來看,可以將IO流分為輸入流和輸出流
????????? 輸入流:數(shù)據(jù)信息從某個(gè)地方流向程序中
????????? 輸出流:數(shù)據(jù)信息從程序中發(fā)送到某個(gè)目的地
? (2)從流的數(shù)據(jù)處理單位來看,可以將IO流分為字節(jié)流和字符流
????????? 字節(jié)流:以字節(jié)方式處理的二進(jìn)制數(shù)據(jù)
????????? 字符流:以字符方式處理的數(shù)據(jù)流(Java使用Unicode字符集,存放一個(gè)字符需要兩個(gè)字節(jié))
? (3)從流的功能來看,可以將IO流分為節(jié)點(diǎn)流和過濾流
????????? 節(jié)點(diǎn)流:程序中用于直接操作目標(biāo)設(shè)備所對(duì)應(yīng)的IO流
????????? 過濾流(也稱為包裝流):通過一個(gè)間接IO流去調(diào)用相應(yīng)的節(jié)點(diǎn)流,以更加靈活方便地讀/寫各種類型的數(shù)據(jù)
二、字節(jié)流和字符流
1.java.io包中有兩大繼承體系:
?? 一類是以字節(jié)為單位處理數(shù)據(jù)的Stream,它們的命名方式都是***Stream
?? 另一類是以字符為單位處理數(shù)據(jù)的Reader和Writer,它們的命名方式都是*Reader或*Writer
三、文件及文件流
1.Java中IO流操作的基本流程
?? 使用File類定位一個(gè)文件->通過字節(jié)流或字符流的子類進(jìn)行流對(duì)象的實(shí)例化
?? ->進(jìn)行讀寫操作->關(guān)閉字節(jié)或字符流
2.Java字節(jié)流和字符流的區(qū)別:在字符流進(jìn)行操作時(shí)會(huì)使用到緩沖區(qū),字節(jié)流操作不會(huì)使用緩沖區(qū)
import java.io.*; class FileStream {public static void main(String[] args) {try {File inFile = new File("file1.txt");File outFile = new File("file2.txt");FileReader fis = new FileReader(inFile);FileWriter fos = new FileWriter(outFile);int c;while ((c = fis.read()) != -1) {fos.write(c);}fis.close();//fos.close();fos.flush(); //若無此語句,file2.txt文件為空} catch(FileNotFoundException e) {System.out.println("FileStream: " + e);} catch (IOException e) {System.out.println("FileStream: " + e);}} }?? flush();語句強(qiáng)制緩沖區(qū)輸出,若使用FileInputStream字節(jié)流操作則無該技術(shù)
?? 字符流在緩沖區(qū)未滿前先存放在緩沖區(qū)中,除非使用flush() 或 close()強(qiáng)制輸出
3.在Windows系統(tǒng)下文件名稱分隔符使用"/"或轉(zhuǎn)義字符"\\"
?? 而Linux中使用"/"
?? 為了保持Java系統(tǒng)很好的可移植性,在操作文件時(shí)最好使用File.separator
?? 例:File f = new FIle("D:" + File.seperator + "test.txt");
?? 一般使用"./"表示當(dāng)前目錄,"../"表示當(dāng)前目錄的父目錄
4.隨機(jī)文件讀寫:RandomAccessFile類
?? 訪問模式值及含義
| mode值 | 含義 |
| "r" | 以只讀方式打開 |
| "rw" | 打開以便讀取和寫入,如果該文件不存在,則嘗試創(chuàng)建該文件 |
| "rws" | 同步讀/寫,任何寫操作的內(nèi)容都被直接寫入物理文件,包括文件內(nèi)容和文件屬性 |
| "rwd" | 同步讀/寫,任何寫操作的內(nèi)容都被直接寫入物理文件,不包括文件屬性 |
?? "rw"模式時(shí),僅當(dāng)RandomAccessFile類對(duì)象執(zhí)行close方法時(shí)才將更新內(nèi)容寫入文件
?? 而"rws"和"rwd"模式是同步讀/寫,因此可以保證數(shù)據(jù)實(shí)時(shí)更新
?? RandomAccessFile類一般方法
| 方法名稱 | 含義 |
| public long getFilePointer() throws IOException | 返回當(dāng)前的文件指針位置 |
| public void seek(long pos) throws IOException | 移動(dòng)文件指針到pos位置 |
| public int skipBytes(int n) throws IOException | 文件指針向后移動(dòng)n個(gè)字節(jié),n為負(fù)數(shù)時(shí)指針不移動(dòng) |
| public int read(byte[] b) throws IOException | 將最多b.length個(gè)字節(jié)讀入數(shù)組b |
| public void write(byte[] b) throws IOException | 將b.length個(gè)字節(jié)從指定數(shù)組b寫入到文件 |
| public final byte readByte() throws IOException | 讀取一個(gè)字節(jié) |
| public final void writeByte(int v) throws IOException | 將(byte) v寫入文件 |
| public final String readLine() throws IOException | 讀取一行 |
| public void close() throws IOException | 關(guān)閉流 |
四、過濾流
1.緩沖流
?? 為提高IO流的讀取效率,Java提供了具有緩沖功能的流類,使用這些流類時(shí),會(huì)創(chuàng)建一個(gè)內(nèi)部的緩沖區(qū)。
?? 在讀字節(jié)或字符時(shí),先從數(shù)據(jù)源讀取到的數(shù)據(jù)填充到緩沖區(qū),然后再返回
?? 在寫字節(jié)或字符時(shí),先把寫入的數(shù)據(jù)填充到內(nèi)部緩沖區(qū),然后一次性寫入到目標(biāo)數(shù)據(jù)源中,從而提高了I/O流的讀取效率
?? 緩沖流包括:
?? 字節(jié)流:BufferedInputStream??? BufferedOutputStream
?? 字符流:BufferedReader??? BufferedWriter
?? 注意:緩沖區(qū)的大小默認(rèn)為32字節(jié)大小,一般緩沖區(qū)的大小為內(nèi)存頁或磁盤塊等的整數(shù)倍
??????????? 只有緩沖區(qū)滿時(shí),才會(huì)將數(shù)據(jù)真正送到輸出流,但可以使用flush()方法人為地將尚未填滿的緩沖區(qū)中的數(shù)據(jù)送出
2.數(shù)據(jù)流:DataInputStream 和 DataOutputStream
?? 作用:允許程序按與機(jī)器無關(guān)的風(fēng)格讀取Java原始數(shù)據(jù),即不關(guān)心一個(gè)數(shù)值應(yīng)當(dāng)是多少字節(jié)
例:
import java.io.IOException; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; public class DataStreamDemo {public static void main(String[] args) throws IOException {//write the dataFileOutputStream fos = new FileOutputStream("data.txt");DataOutputStream dos = new DataOutputStream(fos);dos.writeBoolean(true);dos.writeByte((byte)123);dos.writeChar('J');dos.writeDouble(3.1415926);dos.writeFloat(2.7182f);dos.writeInt(1234567);dos.writeLong(998877665544332211L);dos.writeShort((short)11223);dos.close();//read the dataFileInputStream fis = new FileInputStream("data.txt");DataInputStream dis = new DataInputStream(fis);System.out.println(dis.readBoolean());System.out.println(dis.readByte());System.out.println(dis.readChar());System.out.println(dis.readDouble());System.out.println(dis.readFloat());System.out.println(dis.readInt());System.out.println(dis.readLong());System.out.println(dis.readShort());dis.close();} }3.打印流:使輸出信息更方便的類,主要包含PrintStream和PrintWriter
?? 包含輸出方法print? println? printf
五、標(biāo)準(zhǔn)流
1.語言包java.lang中的System類管理標(biāo)準(zhǔn)IO流和錯(cuò)誤流。System是final類,System類中定義了以下三個(gè)靜態(tài)變量成員變量
?? public static final InputStream in:標(biāo)準(zhǔn)輸入,一般是鍵盤
?? public static final PrintStream out:標(biāo)準(zhǔn)輸出,一般是顯示器
?? public static final PrintStream err:錯(cuò)誤信息輸出,通常是顯示器
例:
public class SystemDemo {public static void main(String[] args) {try {byte bArray[] = new byte[20];String str;System.out.print("Input:");System.in.read(bArray);str = new String(bArray, 0);System.out.print("Output:");System.out.println(str.trim());}catch (IOException ioe) {System.err.println(ioe.toStirng());}} }六、對(duì)象流
1.對(duì)象的序列化:把一個(gè)對(duì)象變?yōu)槎M(jìn)制的數(shù)據(jù)流的方法,可以實(shí)現(xiàn)對(duì)象的傳輸和存儲(chǔ)
?? 只有實(shí)現(xiàn) java.io.Serializable 接口的類才能被序列化
?? java.io.Serializable接口中沒有任何方法,一個(gè)類聲明實(shí)現(xiàn)java.io.Serializable只是表明該類加入對(duì)象序列化協(xié)議
2.對(duì)象流
?? 類ObjectOutputStream和ObjectInputStream繼承了接口ObjectOutput和ObjectInput
?? 將數(shù)據(jù)流功能擴(kuò)展到可以讀/寫對(duì)象,方法:readObject(); 和 writeObject();
?? 注:通常,只要某個(gè)類實(shí)現(xiàn)了Serializable接口,那么該類的類對(duì)象中的所有屬性都會(huì)被串行化
???????? 對(duì)于一些敏感信息,只需在不串行化的屬性上用 transient 修飾即可
七、Scanner類
1.Scanner類處于java.util包中,使用時(shí)需要import引入
?? Scanner類常用方法
| 方法名稱 | 含義 |
| public Scanner(InputStream source) | 從指定字節(jié)輸入流中接收內(nèi)容 |
| public Scanner(File source) throws FileNotFoundException | 從文件中接收內(nèi)容 |
| public boolean hasNextInt() | 判斷輸入的是否是整數(shù) |
| public boolean hasNextDouble() | 判斷輸入的是否是小數(shù) |
| public String next() | 接收數(shù)據(jù) |
| public int nextInt() | 接收整數(shù) |
| public float nextDOuble() | 接收小數(shù) |
| public Scanner useDelimiter(String pattern) | 設(shè)置分隔符 |
例:
Scanner reader = new Scanner(System.in); while(reader.hasNextDouble()) {double x = reader.nextDouble(); }八、流的選擇
1.步驟:
? (1)選擇合適的節(jié)點(diǎn)流:按照鏈接的數(shù)據(jù)源種類進(jìn)行選擇
???????????????????????????????????? 讀寫文件應(yīng)該使用文件流,讀寫字節(jié)數(shù)組應(yīng)該使用字節(jié)數(shù)組流
? (2)選擇合適方向的流:讀:輸入流/寫:輸出流
? (3)選擇字節(jié)流或字符流:所有的文件在傳輸時(shí)都是以字節(jié)的方式進(jìn)行的(包括圖片等)
??????????????????????????????????????? 而字符時(shí)只有在內(nèi)存中才會(huì)形成的,因此字節(jié)流使用較廣泛
? (4)包裝流:可以選擇多個(gè),例如:
????????????????????? 如果需要讀/寫格式化數(shù)據(jù),選擇DataInputStream/DataOutputStream
????????????????????? 如果需要提高讀/寫的效率,選擇BufferedReader/BufferedWriter
轉(zhuǎn)載于:https://www.cnblogs.com/trj14/p/4300462.html
總結(jié)
以上是生活随笔為你收集整理的Java学习笔记-7.Java IO流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SICP练习】66 练习2.37
- 下一篇: Java并发编程之ConcurrentH