java_IO总结(一)
所謂IO,也就是Input與Output的縮寫。在java中,IO涉及的范圍比較大,這里主要討論針對文件內(nèi)容的讀寫
其他知識點將放置后續(xù)章節(jié)(我想,文章太長了,誰都沒耐心翻到最后)
?
對于文件內(nèi)容的操作主要分為兩大類
分別是:
字符流
字節(jié)流
其中,字符流有兩個抽象類:Writer ??Reader
其對應(yīng)子類FileWriter和FileReader可實現(xiàn)文件的讀寫操作
BufferedWriter和BufferedReader能夠提供緩沖區(qū)功能,用以提高效率
?
同樣,字節(jié)流也有兩個抽象類:InputStream???OutputStream
其對應(yīng)子類有FileInputStream和FileOutputStream實現(xiàn)文件讀寫
BufferedInputStream和BufferedOutputStream提供緩沖區(qū)功能
?
俺當(dāng)初學(xué)IO的時候犯了不少迷糊,網(wǎng)上有些代碼也無法通過編譯,甚至風(fēng)格都很大不同,所以新手請注意:? ? ? ?
??????? 1.本文代碼較長,不該省略的都沒省略,主要是因為作為一個新手需要養(yǎng)成良好的代碼編寫習(xí)慣
2.本文在linux下編譯,類似于File.pathSeparator和File.separator這種表示方法是出于跨平臺性和健壯性考慮
3.代碼中有些操作有多種執(zhí)行方式,我采用了方式1...方式2...的表述,只需輕輕解開注釋便可編譯
4.代碼中并沒有在主方法上拋出異常,而是分別捕捉,造成代碼過長,如果僅是測試,或者不想有好的編程習(xí)慣,那你就隨便拋吧……
??????? 5.功能類似的地方就沒有重復(fù)寫注釋了,如果新手看不懂下面的代碼,那肯定是上面的沒有理解清楚
?
字符流
實例1:字符流的寫入
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import?java.io.File; import?java.io.FileWriter; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ????????? ????????//創(chuàng)建要操作的文件路徑和名稱 ????????//其中,File.separator表示系統(tǒng)相關(guān)的分隔符,Linux下為:/? Windows下為:\\ ????????String path = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????? ????????//由于IO操作會拋出異常,因此在try語句塊的外部定義FileWriter的引用 ????????FileWriter w =?null; ????????try?{ ????????????//以path為路徑創(chuàng)建一個新的FileWriter對象 ????????????//如果需要追加數(shù)據(jù),而不是覆蓋,則使用FileWriter(path,true)構(gòu)造方法 ????????????w =?new?FileWriter(path); ????????????? ????????????//將字符串寫入到流中,\r\n表示換行想有好的 ????????????w.write("Nerxious is a good boy\r\n"); ????????????//如果想馬上看到寫入效果,則需要調(diào)用w.flush()方法 ????????????w.flush(); ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????//如果前面發(fā)生異常,那么是無法產(chǎn)生w對象的 ????????????//因此要做出判斷,以免發(fā)生空指針異常 ????????????if(w !=?null) { ????????????????try?{ ????????????????????//關(guān)閉流資源,需要再次捕捉異常 ????????????????????w.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
編譯之后,在目錄下面生成文件,并寫入字符串
?
實例2:字符流的讀取
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import?java.io.File; import?java.io.FileReader; import?java.io.IOException; public?class?Demo2 { ????public?static?void?main(String[] args ) { ????????String path = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????????FileReader r =?null; ????????try?{ ????????????r =?new?FileReader(path); ????????????? ????????????//方式一:讀取單個字符的方式 ????????????//每讀取一次,向下移動一個字符單位 ????????????int?temp1 = r.read(); ????????????System.out.println((char)temp1); ????????????int?temp2 = r.read(); ????????????System.out.println((char)temp2); ????????????????????????? ????????????//方式二:循環(huán)讀取 ????????????//read()方法讀到文件末尾會返回-1 ????????????/* ????????????while (true) { ????????????????int temp = r.read(); ????????????????if (temp == -1) { ????????????????????break; ????????????????} ????????????????System.out.print((char)temp); ????????????} ????????????*/ ????????????? ????????????//方式三:循環(huán)讀取的簡化操作 ????????????//單個字符讀取,當(dāng)temp不等于-1的時候打印字符 ????????????/*int temp = 0; ????????????while ((temp = r.read()) != -1) { ????????????????System.out.print((char)temp); ????????????} ????????????*/ ????????????? ????????????//方式四:讀入到字符數(shù)組 ????????????/* ????????????char[] buf = new char[1024]; ????????????int temp = r.read(buf); ????????????//將數(shù)組轉(zhuǎn)化為字符串打印,后面參數(shù)的意思是 ????????????//如果字符數(shù)組未滿,轉(zhuǎn)化成字符串打印后尾部也許會出現(xiàn)其他字符 ????????????//因此,讀取的字符有多少個,就轉(zhuǎn)化多少為字符串 ????????????System.out.println(new String(buf,0,temp)); ????????????*/ ????????????? ????????????//方式五:讀入到字符數(shù)組的優(yōu)化 ????????????//由于有時候文件太大,無法確定需要定義的數(shù)組大小 ????????????//因此一般定義數(shù)組長度為1024,采用循環(huán)的方式讀入 ????????????/* ????????????char[] buf = new char[1024]; ????????????int temp = 0; ????????????while((temp = r.read(buf)) != -1) { ????????????????System.out.print(new String(buf,0,temp)); ????????????} ????????????*/ ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????if(r !=?null) { ????????????????try?{ ????????????????????r.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
編譯之后的效果:
?
實例3:文本文件的復(fù)制
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import?java.io.File; import?java.io.FileReader; import?java.io.FileWriter; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ????????? ????????String doc = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????????? ????????String copy = File.separator +?"home"?+ File.separator +?"siu"?+ ?????????????????????File.separator +?"life"?+ File.separator +?"lrc.txt"; ????????FileReader r =?null; ????????FileWriter w =?null; ????????try?{ ????????????r =?new?FileReader(doc); ????????????w =?new?FileWriter(copy); ????????????? ????????????//方式一:單個字符寫入 ????????????int?temp =?0; ????????????while((temp = r.read()) != -1) { ????????????????w.write(temp); ????????????} ????????????? ????????????//方式二:字符數(shù)組方式寫入 ????????????/* ????????????char[] buf = new char[1024]; ????????????int temp = 0; ????????????while ((temp = r.read(buf)) != -1) { ????????????????w.write(new String(buf,0,temp)); ????????????} ????????????*/ ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????//分別判斷是否空指針引用,然后關(guān)閉流 ????????????if(r !=?null) { ????????????????try?{ ????????????????????r.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????????if(w !=?null) { ????????????????try?{ ????????????????????w.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
?編譯之后,產(chǎn)生life目錄下的lrc.txt文件,復(fù)制成功
?
實例4:利用字符流的緩沖區(qū)來進行文本文件的復(fù)制
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | import?java.io.BufferedReader; import?java.io.BufferedWriter; import?java.io.File; import?java.io.FileReader; import?java.io.FileWriter; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ????????? ????????String doc = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????????? ????????String copy = File.separator +?"home"?+ File.separator +?"siu"?+ ?????????????????????File.separator +?"life"?+ File.separator +?"lrc.txt"; ????????FileReader r =?null; ????????FileWriter w =?null; ????????//創(chuàng)建緩沖區(qū)的引用 ????????BufferedReader br =?null; ????????BufferedWriter bw =?null; ????????try?{ ????????????r =?new?FileReader(doc); ????????????w =?new?FileWriter(copy); ????????????//創(chuàng)建緩沖區(qū)對象 ????????????//將需要提高效率的FileReader和FileWriter對象放入其構(gòu)造函數(shù)內(nèi) ????????????//當(dāng)然,也可以使用匿名對象的方式 br = new BufferedReader(new FileReader(doc)); ????????????br =?new?BufferedReader(r); ????????????bw =?new?BufferedWriter(w); ????????????? ????????????String line =?null; ????????????//讀取行,直到返回null ????????????//readLine()方法只返回?fù)Q行符之前的數(shù)據(jù) ????????????while((line = br.readLine()) !=?null) { ????????????????//使用BufferWriter對象的寫入方法 ????????????????bw.write(line); ????????????????//寫完文件內(nèi)容之后換行 ????????????????//newLine()方法依據(jù)平臺而定 ????????????????//windows下的換行是\r\n ????????????????//Linux下則是\n ????????????????bw.newLine(); ????????????}?????? ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????//此處不再需要捕捉FileReader和FileWriter對象的異常 ????????????//關(guān)閉緩沖區(qū)就是關(guān)閉緩沖區(qū)中的流對象 ????????????if(br !=?null) { ????????????????try?{ ????????????????????r.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????????if(bw !=?null) { ????????????????try?{ ????????????????????bw.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
?
字節(jié)流
實例5:字節(jié)流的寫入
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import?java.io.File; import?java.io.FileOutputStream; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ?????????? ????????String path = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????????? ????????FileOutputStream o =?null; ????????? ????????try?{ ????????????o =?new?FileOutputStream(path); ????????????String str =?"Nerxious is a good boy\r\n"; ????????????byte[] buf = str.getBytes(); ????????????//也可以直接使用o.write("String".getBytes()); ????????????//因為字符串就是一個對象,能直接調(diào)用方法 ????????????o.write(buf); ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????if(o !=?null) { ????????????????try?{ ????????????????????o.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ???? ????} } |
編譯之后產(chǎn)生的文件,以上在字符串中加\r\n就是為了便于終端顯示
其實在linux下面換行僅用\n即可
?
實例6:字節(jié)流的讀取
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import?java.io.File; import?java.io.FileInputStream; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ?????????? ????????String path = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"demo.txt"; ????????? ????????FileInputStream i =?null; ????????? ????????try?{ ????????????i =?new?FileInputStream(path); ????????????? ????????????//方式一:單個字符讀取 ????????????//需要注意的是,此處我用英文文本測試效果良好 ????????????//但中文就悲劇了,不過下面兩個方法效果良好 ????????????int?ch =?0; ????????????while((ch=i.read()) != -1){ ????????????????System.out.print((char)ch); ????????????} ????????????? ????????????//方式二:數(shù)組循環(huán)讀取 ????????????/* ????????????byte[] buf = new byte[1024]; ????????????int len = 0; ????????????while((len = i.read(buf)) != -1) { ????????????????System.out.println(new String(buf,0,len)); ????????????} ????????????*/ ????????????? ????????????? ????????????//方式三:標(biāo)準(zhǔn)大小的數(shù)組讀取 ????????????/* ????????????//定一個一個剛好大小的數(shù)組 ????????????//available()方法返回文件的字節(jié)數(shù) ????????????//但是,如果文件過大,內(nèi)存溢出,那就悲劇了 ????????????//所以,親們要慎用!!!上面那個方法就不錯 ????????????byte[] buf = new byte[i.available()]; ????????????i.read(buf); ????????????//因為數(shù)組大小剛好,所以轉(zhuǎn)換為字符串時無需在構(gòu)造函數(shù)中設(shè)置起始點 ????????????System.out.println(new String(buf)); ????????????*/ ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????if(i !=?null) { ????????????????try?{ ????????????????????i.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ???? ????} } |
?讀取文件到終端
?
實例7:二進制文件的復(fù)制
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import?java.io.File; import?java.io.FileInputStream; import?java.io.FileOutputStream; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ?????????? ????????String bin = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"一個人生活.mp3"; ????????? ????????String copy = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"life"?+ File.separator +?"一個人生活.mp3"; ????????? ????????FileInputStream i =?null; ????????FileOutputStream o =?null; ????????? ????????try?{ ????????????i =?new?FileInputStream(bin); ????????????o =?new?FileOutputStream(copy); ????????????? ????????????//循環(huán)的方式讀入寫出文件,從而完成復(fù)制 ????????????byte[] buf =?new?byte[1024]; ????????????int?temp =?0; ????????????while((temp = i.read(buf)) != -1) { ????????????????o.write(buf,?0, temp); ????????????} ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????if(i !=?null) { ????????????????try?{ ????????????????????i.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????????if(o !=?null) { ????????????????try?{ ????????????????????o.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
?復(fù)制效果,如圖:
?
?實例8:利用字節(jié)流的緩沖區(qū)進行二進制文件的復(fù)制
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import?java.io.BufferedInputStream; import?java.io.BufferedOutputStream; import?java.io.File; import?java.io.FileInputStream; import?java.io.FileOutputStream; import?java.io.IOException; public?class?Demo { ????public?static?void?main(String[] args ) { ?????????? ????????String bin = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"work"?+ File.separator +?"一個人生活.mp3"; ????????? ????????String copy = File.separator +?"home"?+ File.separator +?"siu"?+ ??????????????????????File.separator +?"life"?+ File.separator +?"一個人生活.mp3"; ????????? ????????FileInputStream i =?null; ????????FileOutputStream o =?null; ????????BufferedInputStream bi =?null; ????????BufferedOutputStream bo =?null; ????????? ????????try?{ ????????????i =?new?FileInputStream(bin); ????????????o =?new?FileOutputStream(copy); ????????????bi =?new?BufferedInputStream(i); ????????????bo =?new?BufferedOutputStream(o); ????????????? ????????????byte[] buf =?new?byte[1024]; ????????????int?temp =?0; ????????????while((temp = bi.read(buf)) != -1) { ????????????????bo.write(buf,0,temp); ????????????} ????????????? ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?finally?{ ????????????if(bi !=?null) { ????????????????try?{ ????????????????????i.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????????if(bo !=?null) { ????????????????try?{ ????????????????????o.close(); ????????????????}?catch?(IOException e) { ????????????????????e.printStackTrace(); ????????????????} ????????????} ????????} ????} } |
?兩個目錄都有 “一個人生活.mp3”文件,順便說一下,這歌挺好聽的
?
初學(xué)者在學(xué)會使用字符流和字節(jié)流之后未免會產(chǎn)生疑問:什么時候該使用字符流,什么時候又該使用字節(jié)流呢?
其實仔細(xì)想想就應(yīng)該知道,所謂字符流,肯定是用于操作類似文本文件或者帶有字符文件的場合比較多
而字節(jié)流則是操作那些無法直接獲取文本信息的二進制文件,比如圖片,mp3,視頻文件等
說白了在硬盤上都是以字節(jié)存儲的,只不過字符流在操作文本上面更方便一點而已
此外,為什么要利用緩沖區(qū)呢?
我們知道,像迅雷等下載軟件都有個緩存的功能,硬盤本身也有緩沖區(qū)
試想一下,如果一有數(shù)據(jù),不論大小就開始讀寫,勢必會給硬盤造成很大負(fù)擔(dān),它會感覺很不爽
人不也一樣,一頓飯不讓你一次吃完,每分鐘喂一勺,你怎么想?
因此,采用緩沖區(qū)能夠在讀寫大文件的時候有效提高效率
轉(zhuǎn)載于:https://www.cnblogs.com/deepbreath/p/4138600.html
總結(jié)
以上是生活随笔為你收集整理的java_IO总结(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# ref跟out
- 下一篇: 当一个线程进入一个对象的一个synchr