Java IO流 详解(字节流、字符流、输入流、输出流、刷新)
一、IO流概述
? ? ? ? ? I:Input輸入? 從其他存儲(chǔ)設(shè)備【讀】數(shù)據(jù)到內(nèi)存中? 輸入過(guò)程
????????O:OutPut輸出? 從內(nèi)存中【寫(xiě)】數(shù)據(jù)到其他存儲(chǔ)設(shè)備? 輸出過(guò)程
二、IO流分類(lèi)
? ? ? ? 1.根據(jù)數(shù)據(jù)的類(lèi)型分為:
? ? ? ? ? ? ? ? 【字節(jié)流】和【字符流】
????????????????【字節(jié)流】:以字節(jié)為基本單位,讀寫(xiě)數(shù)據(jù)的流
??? ????????????????????????字節(jié)輸入流:以字節(jié)為基本單位,讀數(shù)據(jù)
??? ????????????????????????字節(jié)輸出流:以字節(jié)為基本單位,寫(xiě)出數(shù)據(jù)
????????????????【字符流】:以字符為基本單位,讀寫(xiě)數(shù)據(jù)的流
??????????????????? ????????字符輸入流:以字符為基本單位,讀數(shù)據(jù)
??????????????????? ????????字符輸出流:以字符為基本單位,寫(xiě)出數(shù)據(jù)
? ? ? ? 2.根據(jù)數(shù)據(jù)的流向分為:
? ? ? ? ? ? ? ? 【輸入流】和【輸出流】
? ? ? ? ? ? ? ? 【輸入流】:把數(shù)據(jù)從 其他存儲(chǔ)設(shè)備 上【讀取】到 內(nèi)存 中的流
?? ????????????????????????字節(jié)輸入流:以字節(jié)為基本單位,讀數(shù)據(jù)
?? ????????????????????????字符輸入流:以字符為基本單位,讀數(shù)據(jù)
? ? ? ? ? ? ? ? 【輸出流】:把數(shù)據(jù)從 內(nèi)存 中【寫(xiě)出】到 其他 存儲(chǔ) 設(shè)備中的流
?????????????????????????? 字節(jié)輸出流:以字節(jié)為基本單位,寫(xiě)出數(shù)據(jù)
?????????????????????????? 字符輸出流:以字符為基本單位,寫(xiě)出數(shù)據(jù)
? ? ? ? 3.IO流的頂層父類(lèi)
? ? ? ? ? ? ? ? - 字節(jié)輸入流:頂層父類(lèi):InputStream --> 抽象類(lèi)?? 常見(jiàn)子類(lèi):FileInputStream
????????????????- 字節(jié)輸出流:頂層父類(lèi):OutputStream --> 抽象類(lèi)?? 常見(jiàn)子類(lèi):FileOutputStream
????????????????- 字符輸入流:頂層父類(lèi):Reader --> 抽象類(lèi)?? 常見(jiàn)子類(lèi):FileReader
????????????????- 字符輸出流:頂層父類(lèi):Writer --> 抽象類(lèi)?? 常見(jiàn)子類(lèi):FileWriter
?
三、字節(jié)輸出流OutPutStream
????????OutputStream 輸出流頂層父類(lèi)
??????????? java.io.OutputStream抽象類(lèi)是所有【字節(jié)輸出流】的父類(lèi),用來(lái)【寫(xiě)】出字節(jié)輸出流
??????????? 成員方法:
??????????????? - public void close():關(guān)閉次輸出流并釋放與此流相關(guān)聯(lián)的任何系統(tǒng)資源
? ? ? ? ? ? ? ? - close方法,當(dāng)完成流的操作時(shí),必須調(diào)用此方法,釋放系統(tǒng)資源,否則數(shù)據(jù)寫(xiě)入不完整或消失
??????? ????????- public abstract void write(int b):將指定的字節(jié)寫(xiě)入輸出流【一個(gè)字節(jié)一個(gè)字節(jié)寫(xiě)入到硬盤(pán)】
??????????????? - public void write(byte b[]):將 b.length字節(jié)從指定的字節(jié)數(shù)組寫(xiě)入到此輸出流【以字節(jié)數(shù)組的形式寫(xiě)入到硬盤(pán)】
??????????????? - public void write(byte b[],int off, int len):將指定范圍的字節(jié)數(shù)組的字節(jié)數(shù)據(jù)寫(xiě)到此輸出流中【將字節(jié)數(shù)組中某一段字節(jié)數(shù)據(jù)寫(xiě)到硬盤(pán)】
? ? ? ? ? ?方法逐個(gè)演示:
? ? ? ? ? ? ? ? 1.寫(xiě)出單個(gè)字節(jié)數(shù)據(jù)
// 1.創(chuàng)建字節(jié)輸出流對(duì)象 路徑文件必須真實(shí)存在FileOutputStream fos1 = new FileOutputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 2.寫(xiě)出 單個(gè)字節(jié)的數(shù)據(jù)fos1.write(72);// 寫(xiě)入的一個(gè)字節(jié)數(shù)據(jù),我們是往文本文檔寫(xiě)入字節(jié)數(shù)據(jù),但是因?yàn)槭俏谋绢?lèi)型,需要將字節(jié)數(shù)據(jù)轉(zhuǎn)換成文本數(shù)據(jù),文本就是字符fos1.write(105);fos1.write(33);// 3.關(guān)閉流,釋放資源fos1.close();? ? ? ? (運(yùn)行結(jié)束,會(huì)在對(duì)應(yīng)的文件中生成對(duì)應(yīng)的字節(jié),代碼中寫(xiě)入的數(shù)字為ASCII碼,每個(gè)數(shù)字對(duì)應(yīng)一個(gè)字母)
? ? ? ? ? ? ? ? ?2.寫(xiě)出字節(jié)數(shù)組數(shù)據(jù)
//1.創(chuàng)建字節(jié)輸出流對(duì)象 真實(shí)存在的路徑FileOutputStream fos1 = new FileOutputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 2.創(chuàng)建字節(jié)數(shù)組byte[] bytes = {97,98,99};// 3.寫(xiě)出字節(jié)數(shù)組中的字節(jié)數(shù)據(jù)fos1.write(bytes);// 4.關(guān)閉流,釋放資源fos1.close();?(運(yùn)行結(jié)束,會(huì)在對(duì)應(yīng)的文件中生成對(duì)應(yīng)的字節(jié),代碼中寫(xiě)入的數(shù)字為ASCII碼,每個(gè)數(shù)字對(duì)應(yīng)一個(gè)字母)
????????????????3.寫(xiě)出指定范圍字節(jié)數(shù)組的數(shù)據(jù)
// 1.創(chuàng)建字節(jié)輸出流對(duì)象 真實(shí)存在的路徑FileOutputStream fos1 = new FileOutputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 2.創(chuàng)建字節(jié)數(shù)組byte[] bytes = {97,98,99};// 3.寫(xiě)出字節(jié)數(shù)組中的字節(jié)數(shù)據(jù)fos1.write(bytes,1,2);// 4.關(guān)閉流,釋放資源fos1.close();?(運(yùn)行結(jié)束,會(huì)在對(duì)應(yīng)的文件中生成對(duì)應(yīng)的字節(jié),代碼中寫(xiě)入的數(shù)字為ASCII碼,每個(gè)數(shù)字對(duì)應(yīng)一個(gè)字母)
? ? ? ? ? ? ? ??4.數(shù)組追加續(xù)寫(xiě)
// 1.創(chuàng)建字節(jié)輸出流對(duì)象 真實(shí)存在的路徑FileOutputStream fos1 = new FileOutputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt",true);// 2.創(chuàng)建字節(jié)數(shù)組byte[] bytes = {97,98,99,100};// 3.寫(xiě)出字節(jié)數(shù)組中的字節(jié)數(shù)據(jù)fos1.write(bytes,1,2);// 4.關(guān)閉流,釋放資源fos1.close();? ? ? ? ? ? ? ?
(這里續(xù)寫(xiě)是沿著第三個(gè)練習(xí)續(xù)寫(xiě)的,第三個(gè)練習(xí)寫(xiě)了 “bc”,這里也續(xù)寫(xiě)一個(gè)“bc”,不續(xù)寫(xiě)的話(huà),同一個(gè)文件的數(shù)據(jù)會(huì)被覆蓋)
????????5.寫(xiě)出換行
/** 需求: 寫(xiě)一首詩(shī)* 鵝鵝鵝,* 曲項(xiàng)向天歌。* 白毛浮綠水,* 紅掌撥清波。* */// 1.創(chuàng)建字節(jié)輸出流對(duì)象,關(guān)聯(lián)到 day12\resources\a.txt 真實(shí)存在FileOutputStream fos1 = new FileOutputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 2.創(chuàng)建字節(jié)數(shù)組byte[] bytes = {97,98,99,100};// 3.寫(xiě)出字節(jié)數(shù)組中的字節(jié)數(shù)據(jù)fos1.write("鵝鵝鵝,".getBytes());fos1.write("\r\n".getBytes());fos1.write("曲項(xiàng)向天歌。".getBytes());fos1.write("\r\n".getBytes());fos1.write("白毛浮綠水,".getBytes());fos1.write("\r\n".getBytes());fos1.write("紅掌撥清波。".getBytes());// 4.關(guān)閉流,釋放資源fos1.close();四、字節(jié)輸入流InputStream
????????java.io.InputStream 抽象類(lèi),給類(lèi)是所有字節(jié)輸入流的父類(lèi),用于讀取字節(jié)數(shù)據(jù)
? ? ? ? 構(gòu)造方法:
????????????????概述:java.io.FileInputStream類(lèi)是InputStream的實(shí)現(xiàn)子類(lèi),表示字節(jié)輸入流,用于讀取數(shù)據(jù)
????????????????- public FileInputStream(String name):通過(guò)打開(kāi)與實(shí)際文件的連接來(lái)創(chuàng)建一個(gè)字節(jié)輸入流對(duì)象,該文件由文件系統(tǒng)的路徑名 name命名
????????????????- public FileInputStream(File file):通過(guò)打開(kāi)與實(shí)際文件的連接來(lái)創(chuàng)建一個(gè)字節(jié)輸入流對(duì)象,該文件由文件系統(tǒng)中的文件對(duì)象file命名
? ? ? ? 成員方法:
????????????????- public void close():關(guān)閉輸入流并釋放與此流相關(guān)的任何系統(tǒng)資源
????????????????- public abstract int read():從輸入流讀取數(shù)據(jù)的下一個(gè)字節(jié),每次讀取一個(gè)字節(jié)
? ? ? ? ? ? ? ? - public int read(byte b[]):從輸入流讀取一些字節(jié)數(shù)據(jù),并將它們存儲(chǔ)到字節(jié)數(shù)住b中
? ? ? ? 方法逐一演示:
? ? ? ? ? ? ? ??1.構(gòu)造方法
// 創(chuàng)建字節(jié)輸入流對(duì)象,關(guān)聯(lián)數(shù)據(jù)源文件路徑 真實(shí)存在的路徑FileInputStream fileInputStream1 = new FileInputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");FileInputStream fileInputStream2 = new FileInputStream(new File("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt"));// 創(chuàng)建字節(jié)輸入流對(duì)象,關(guān)聯(lián)數(shù)據(jù)源文件路徑 不存在的路徑,會(huì)報(bào)異常:系統(tǒng)找不到指定的文件FileInputStream fileInputStream3 = new FileInputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a1.txt");? ? ? ? ? ? ? ? 2.讀取單個(gè)字節(jié)數(shù)據(jù)
// 創(chuàng)建字節(jié)輸入流對(duì)象,關(guān)聯(lián)數(shù)據(jù)源文件路徑 真實(shí)存在的FileInputStream fileInputStream1 = new FileInputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 定義一個(gè)Int類(lèi)型的變量,用來(lái)存儲(chǔ)讀取到的數(shù)據(jù)int len;// 使用循環(huán)的方式讀取數(shù)據(jù)while ((len = fileInputStream1.read()) != -1){// while循環(huán)中的條件,fis每讀取一個(gè)字節(jié),會(huì)優(yōu)先復(fù)制給len變量,然后拿len變量與 -1 進(jìn)行比較System.out.print((char) len);}// 關(guān)閉流fileInputStream1.close();????????
? ? ? ??(輸出語(yǔ)句中如果不加? char? 強(qiáng)轉(zhuǎn)字符的話(huà),打印出來(lái)的就是ASCII碼,需要強(qiáng)轉(zhuǎn)成字符類(lèi)型)
? ? ? ? ? ? ? ? 3.讀取字節(jié)數(shù)組長(zhǎng)度的字節(jié)數(shù)據(jù)
public static void main (String[] args) throws IOException {// 創(chuàng)建字節(jié)輸入流對(duì)象,關(guān)聯(lián)數(shù)據(jù)源文件路徑 真實(shí)存在的FileInputStream fileInputStream1 = new FileInputStream("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 創(chuàng)建byte[] 數(shù)組,長(zhǎng)度暫定為2,用來(lái)存儲(chǔ)讀取到的字節(jié)數(shù)據(jù)byte[] bytes = new byte[8192];// 定義一個(gè)int類(lèi)型的變量,用來(lái)存儲(chǔ)讀取到的字節(jié)個(gè)數(shù)int len;//while循環(huán)的方式來(lái)遍歷讀取本中的數(shù)據(jù)while ((len = fileInputStream1.read(bytes)) != -1){System.out.println(new String(bytes,0,len));}// 關(guān)閉流fileInputStream1.close();/** 使用數(shù)組讀取的話(huà),每次讀取多個(gè)字節(jié),減少系統(tǒng)之間的IO操作次數(shù),從而提高了讀寫(xiě)的效率,建議開(kāi)發(fā)中如此使用* */}????????
? ? ? ? ? ? ? ? (因?yàn)閿?shù)組不能強(qiáng)轉(zhuǎn),所以用來(lái)String的一個(gè)方法用來(lái)打印數(shù)組)
???
五、字節(jié)流操作文本文件可能存在的問(wèn)題
? ? ? ? ? 1.當(dāng)使用字節(jié)流讀取文本文檔的時(shí)候,可能會(huì)有一些問(wèn)題,遇到中文字符的時(shí)候,可能不會(huì)顯示完整的字符
? ? ? ? ? 2.因?yàn)橐粋€(gè)中文符可能占用多個(gè)字節(jié)存儲(chǔ),所以Java提供了字符流類(lèi),專(zhuān)門(mén)來(lái)操作文本文件,以字符為單位讀寫(xiě)數(shù)據(jù)
六、字符輸入流Reader
????????java.io.Reader類(lèi):抽象類(lèi),表示用于讀取字符流的所有類(lèi)的超類(lèi),可以讀取字符信息到內(nèi)存中
? ? ? ? 構(gòu)造方法:
? ? ? ? ? ? ? ? 概述:java.io.FileReade類(lèi),繼承Reader類(lèi),表示字符輸入流,用來(lái)讀取字符數(shù)據(jù)對(duì)象
?????????????????- public FileReader(String fileName):FileReader類(lèi)對(duì)象,給定要讀取的文件的名稱(chēng)
? ? ? ? ? ? ? ? ?- public FileReader(File file):FileReader類(lèi)對(duì)象,給定要讀取的file文件的名稱(chēng)
? ? ? ? 成員方法:
????????????????- public abstract void close():關(guān)閉此流并釋放與此流相關(guān)的任何系統(tǒng)資源
????????????????- public int read():從輸入流讀取一個(gè)字符,讀取到末尾返回 -1
????????????????- public int read(char cbuf[]):從輸入流中讀取一些數(shù)據(jù),并將它們存儲(chǔ)到字符數(shù)組cbuf中
? ? ? ? ?方法逐一演示:
????????????????(字符的輸入輸出流? ?和? ?字節(jié)的輸入輸出流? ?一樣的效果,有些地方就不加以贅述了)
? ? ? ? ? ? ? ??1.構(gòu)造方法
// 文件真實(shí)存在FileReader fr1 = new FileReader("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");// 文件不存在,會(huì)報(bào)出異常FileReader fr2 = new FileReader("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");? ? ? ? ? ? ? ? 2.讀取單個(gè)字符數(shù)據(jù)
// 創(chuàng)建字符輸入流對(duì)象FileReader fr1 = new FileReader("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\a.txt");int len;// 循環(huán)讀取while ((len = fr1.read()) != -1){System.out.print((char) len);}//關(guān)閉fr1.close();? ? ? ? ? ? ? ?3.讀取字符的數(shù)組長(zhǎng)度的字符數(shù)據(jù)
// 創(chuàng)建字符輸入流對(duì)象FileReader fr1 = new FileReader("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\a.txt");int len;// 每次讀取返回的字符數(shù)據(jù)char[] chars = new char[1024];// 循環(huán)讀取while( (len = fr1.read(chars)) != -1 ){System.out.print(new String(chars,0,len));}// 關(guān)閉流fr1.close();????????
七、字符輸出流Write
?????????java.io.Writer類(lèi),抽象類(lèi),用于表示字符輸出流的所有類(lèi)的超類(lèi),將指定的字符信息寫(xiě)出到目的地
? ? ? ? 構(gòu)造方法:
? ? ? ? ? ? ? ??概述:java.io.FileWriter類(lèi) 是Writer的子類(lèi),表示字符輸出流,可以用來(lái)寫(xiě)出字符數(shù)據(jù)
????????????????- public FileWriter(String fileName)
????????????????- public FileWriter(String fileName, boolean append)
????????????????- public FileWriter(File file)
????????????????- public FileWriter(File file, boolean append)
? ? ? ? ? ? ? ??注意:
????????????????1.當(dāng)你創(chuàng)建一個(gè)字符輸出流對(duì)象時(shí),必須傳入一個(gè)文件路徑
????????????????2.前面2個(gè)構(gòu)造方法,傳入的路徑,如果沒(méi)有這個(gè)文件,會(huì)創(chuàng)建這個(gè)文件,如果文件里面有數(shù)據(jù),數(shù)據(jù)會(huì)被清空
????????????????3.后面2個(gè)構(gòu)造方法,多了一個(gè)append的參數(shù),true表示不清空,false默認(rèn)清空
? ? ? ? 成員方法:
????????????????- public void write(int c)
????????????????- public void write(char cbuf[])
????????????????- public abstract void write(char cbuf[], int off, int len)
????????????????- public void write(String str)
????????????????- public void write(String str, int off, int len)
????????????????- public abstract void flush()
????????????????- public abstract void close()
? ? ? ? 方法逐個(gè)演示:
? ? ? ? ? ? ? ? 1.構(gòu)造方法
FileWriter fw1 = new FileWriter("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\a.txt"); FileWriter fw2 = new FileWriter(new File("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\a.txt"));FileWriter fw3 = new FileWriter("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\a.txt",true); FileWriter fw4 = new FileWriter(new File("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\a.txt"),true);? ? ? ? ? ? ? ?2.寫(xiě)出單個(gè)字符
// 第一步:創(chuàng)建字符輸出流對(duì)象。關(guān)聯(lián)目的地文件路徑FileWriter fw1 = new FileWriter(new File("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\b.txt"));// 第二步:寫(xiě)入單個(gè)字符fw1.write(97);// 第三步:關(guān)閉流fw1.close();? ? ? ? ? ? ? ?
????????????????3.寫(xiě)出字符串
// 第一步:創(chuàng)建字符輸出流對(duì)象。關(guān)聯(lián)目的地文件路徑FileWriter fw1 = new FileWriter("day12_File類(lèi)與遞歸&IO流&字符流和字節(jié)流\\resources\\c.txt");// 第二步:寫(xiě)出字符串String str = "我今天心情真美麗\r\n嘿嘿哈哈";fw1.write(str,3,5);// 第三步:關(guān)閉流fw1.close();?????????
? ? ? ? ? ? ? ??4.寫(xiě)出字符數(shù)組
// 第一步:創(chuàng)建字符輸出流對(duì)象。關(guān)聯(lián)目的地文件路徑FileWriter fw1 = new FileWriter("day12_File類(lèi)與遞歸&IO流&字符流&字節(jié)流\\resources\\c.txt");// 第二步:寫(xiě)出字符數(shù)組char[] chars = {'我','是','一','個(gè)','偉','大','的','人'};fw1.write(chars);// 第三步:關(guān)閉流fw1.close();?????????
?
八、流的關(guān)閉和刷新
????????- public abstract void flush():刷新緩沖區(qū),流對(duì)象可以繼續(xù)使用
??????? - public abstract void close():關(guān)閉流,釋放系統(tǒng)資源,關(guān)閉流會(huì)順帶刷新緩沖區(qū),關(guān)閉之后不可操作
????????
?
總結(jié)
以上是生活随笔為你收集整理的Java IO流 详解(字节流、字符流、输入流、输出流、刷新)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: OTRS6完整安装文档
- 下一篇: Java-字节流