摘要:后綴名是父類名。將字符讀取流對(duì)象作為參數(shù)傳遞給緩沖對(duì)象的構(gòu)造函數(shù)。讀寫失敗讀取關(guān)閉失敗寫入關(guān)閉失敗字節(jié)流操作從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)。和字節(jié)流需求,想要操作圖片數(shù)據(jù)。
概述
IO流用來處理設(shè)備之間的數(shù)據(jù)傳輸,Java對(duì)數(shù)據(jù)的操作是通過流的方式,Java用于操作流的對(duì)象都在IO包中。
流按操作數(shù)據(jù)分為兩種:字節(jié)流與字符流
流按流向分為:輸入流、輸出流
Reader
Writer
注:由這四個(gè)類派生出來的子類名稱都是以其父類名作為子類名的后綴
如:InputStream的子類FileInputStream
如:Reader的子類FileReader
字節(jié)流的抽象基類InputStream
OutputStream
FileWriter 后綴是父類名 前綴名是功能
FileWriter寫文件步驟:
創(chuàng)建一個(gè)FileWrite對(duì)象,該對(duì)象一初始化就必須要明確被操作的文件,而且該文件會(huì)被創(chuàng)建到指定目錄,如果該目錄下已有同名文件則被覆蓋FileWrite fw = new FileWrite("demo.txt");
調(diào)用write方法將字符串寫入到流中fw.write("abcde");
刷新流對(duì)象中的緩沖中的數(shù)據(jù),將數(shù)據(jù)刷到目的地中
fw.flush();//flush刷新后,流可以繼續(xù)使用,close刷新后,流將會(huì)關(guān)閉
fw.close();//關(guān)閉流資源,但關(guān)閉之前會(huì)刷新一次內(nèi)部的緩沖中的數(shù)據(jù),最后必須要關(guān)閉流
代碼示例
/* 需求:在硬盤上,創(chuàng)建一個(gè)文件并寫入一些文字?jǐn)?shù)據(jù)。 找到一個(gè)專門用于操作文件的Writer子類對(duì)象。FileWriter。 后綴名是父類名。 前綴名是該流對(duì)象的功能。 */ import java.io.*; class FileWriterDemo { public static void main(String[] args) throws IOException { //創(chuàng)建一個(gè)FileWriter對(duì)象。該對(duì)象一被初始化就必須要明確被操作的文件。 //而且該文件會(huì)被創(chuàng)建到指定目錄下。如果該目錄下已有同名文件,將被覆蓋。 //其實(shí)該步就是在明確數(shù)據(jù)要存放的目的地。 FileWriter fw = new FileWriter("demo.txt"); //調(diào)用write方法,將字符串寫入到流中。 fw.write("abcde"); //刷新流對(duì)象中的緩沖中的數(shù)據(jù)。 //將數(shù)據(jù)刷到目的地中。 //fw.flush(); //關(guān)閉流資源,但是關(guān)閉之前會(huì)刷新一次內(nèi)部的緩沖中的數(shù)據(jù)。 //將數(shù)據(jù)刷到目的地中。 //和flush區(qū)別:flush刷新后,流可以繼續(xù)使用,close刷新后,會(huì)將流關(guān)閉。 fw.close(); } } /* 演示對(duì)已有文件的數(shù)據(jù)續(xù)寫。 */ import java.io.*; class FileWriterDemo3 { public static void main(String[] args) throws IOException //不能拋,要處理異常//傳遞一個(gè)true參數(shù),代表不覆蓋已有的文件。并在已有文件的末尾處進(jìn)行數(shù)據(jù)續(xù)寫。 FileWriter fw = new FileWriter("demo.txt",true); fw.write("nihao xiexie"); //換行續(xù)寫 fw.close(); } }FileReader字符流讀取
import java.io.*; class FileReaderDemo { public static void main(String[] args) throws IOException { //創(chuàng)建一個(gè)文件讀取流對(duì)象,和指定名稱的文件相關(guān)聯(lián)。 //要保證該文件是已經(jīng)存在的,如果不存在,會(huì)發(fā)生異常FileNotFoundException FileReader fr = new FileReader("demo.txt"); //調(diào)用讀取流對(duì)象的read方法。 //read():一次讀一個(gè)字符。而且會(huì)自動(dòng)往下讀。 int ch = 0; while((ch=fr.read())!=-1) { System.out.println("ch="+(char)ch); } /* while(true) { int ch = fr.read(); if(ch==-1) break; System.out.println("ch="+(char)ch); } */ fr.close(); } }
/* 第二種方式:通過字符數(shù)組進(jìn)行讀取。 常用這種 */ import java.io.*; class FileReaderDemo2 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("demo.txt"); //定義一個(gè)字符數(shù)組。用于存儲(chǔ)讀到字符。 //該read(char[])返回的是讀到字符個(gè)數(shù)。 char[] buf = new char[1024]; int num = 0; while((num=fr.read(buf))!=-1) { System.out.println(new String(buf,0,num)); } fr.close(); } }文件拷貝
//將C盤一個(gè)文本文件復(fù)制到D盤。 /* 復(fù)制的原理: 其實(shí)就是將C盤下的文件數(shù)據(jù)存儲(chǔ)到D盤的一個(gè)文件中。 步驟: 1,在D盤創(chuàng)建一個(gè)文件。用于存儲(chǔ)C盤文件中的數(shù)據(jù)。 2,定義讀取流和C盤文件關(guān)聯(lián)。 3,通過不斷的讀寫完成數(shù)據(jù)存儲(chǔ)。 4,關(guān)閉資源。 */ import java.io.*; class CopyText { public static void main(String[] args) throws IOException { copy_2(); } public static void copy_2() { FileWriter fw = null; FileReader fr = null; try { fw = new FileWriter("SystemDemo_copy.txt"); fr = new FileReader("SystemDemo.java"); char[] buf = new char[1024]; int len = 0; while((len=fr.read(buf))!=-1) { fw.write(buf,0,len); } } catch (IOException e) { throw new RuntimeException("讀寫失敗"); } finally { if(fr!=null) try { fr.close(); } catch (IOException e) { } if(fw!=null) try { fw.close(); } catch (IOException e) { } } } //從C盤讀一個(gè)字符,就往D盤寫一個(gè)字符。 public static void copy_1()throws IOException { //創(chuàng)建目的地。 FileWriter fw = new FileWriter("RuntimeDemo_copy.txt"); //與已有文件關(guān)聯(lián)。 FileReader fr = new FileReader("RuntimeDemo.java"); int ch = 0; while((ch=fr.read())!=-1) { fw.write(ch); } fw.close(); fr.close(); } }BufferedReader字符流緩沖區(qū)讀
從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取
可以指定緩沖區(qū)的大小,或者可以使用默認(rèn)大小。大多數(shù)情況下,默認(rèn)值就足夠大了
/* 字符讀取流緩沖區(qū): 該緩沖區(qū)提供了一個(gè)一次讀一行的方法 readLine,方便于對(duì)文本數(shù)據(jù)的獲取。 當(dāng)返回null時(shí),表示讀到文件末尾。 readLine方法返回的時(shí)候只返回回車符之前的數(shù)據(jù)內(nèi)容。并不返回回車符。 */ import java.io.*; class BufferedReaderDemo { public static void main(String[] args) throws IOException { //創(chuàng)建一個(gè)讀取流對(duì)象和文件相關(guān)聯(lián)。 FileReader fr = new FileReader("buf.txt"); //為了提高效率。加入緩沖技術(shù)。將字符讀取流對(duì)象作為參數(shù)傳遞給緩沖對(duì)象的構(gòu)造函數(shù)。 BufferedReader bufr = new BufferedReader(fr); String line = null; while((line=bufr.readLine())!=null) { System.out.print(line); } bufr.close(); } }BufferedWriter字符流緩沖區(qū)讀
將文本寫入字符輸出流,緩沖各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫入
可以指定緩沖區(qū)的大小,或者接受默認(rèn)的大小。在大多數(shù)情況下,默認(rèn)值就足夠大了
通常 Writer 將其輸出立即發(fā)送到底層字符或字節(jié)流。除非要求提示輸出,否則建議用 BufferedWriter 包裝所有其 write() 操作可能開銷很高的 Writer(如 FileWriters 和 OutputStreamWriters)。
/* 緩沖區(qū)的出現(xiàn)是為了提高流的操作效率而出現(xiàn)的。 所以在創(chuàng)建緩沖區(qū)之前,必須要先有流對(duì)象。 該緩沖區(qū)中提供了一個(gè)跨平臺(tái)的換行符。 newLine(); */ import java.io.*; class BufferedWriterDemo { public static void main(String[] args) throws IOException { //創(chuàng)建一個(gè)字符寫入流對(duì)象。 FileWriter fw = new FileWriter("buf.txt"); //為了提高字符寫入流效率。加入了緩沖技術(shù)。 //只要將需要被提高效率的流對(duì)象作為參數(shù)傳遞給緩沖區(qū)的構(gòu)造函數(shù)即可。 BufferedWriter bufw = new BufferedWriter(fw); for(int x=1; x<5; x++) { bufw.write("abcd"+x); bufw.newLine(); //寫入一個(gè)行分隔符 bufw.flush(); } //記住,只要用到緩沖區(qū),就要記得刷新。 //bufw.flush(); //其實(shí)關(guān)閉緩沖區(qū),就是在關(guān)閉緩沖區(qū)中的流對(duì)象。 bufw.close(); } }通過緩沖區(qū)復(fù)制文本
/* 通過緩沖區(qū)復(fù)制一個(gè).java文件。 */ import java.io.*; class CopyTextByBuf { public static void main(String[] args) { BufferedReader bufr = null; BufferedWriter bufw = null; try { bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java")); bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt")); String line = null; while((line=bufr.readLine())!=null) { bufw.write(line); bufw.newLine(); bufw.flush(); } } catch (IOException e) { throw new RuntimeException("讀寫失敗"); } finally { try { if(bufr!=null) bufr.close(); } catch (IOException e) { throw new RuntimeException("讀取關(guān)閉失敗"); } try { if(bufw!=null) bufw.close(); } catch (IOException e) { throw new RuntimeException("寫入關(guān)閉失敗"); } } } } }字節(jié)流操作
FileInputStream 從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)。哪些文件可用取決于主機(jī)環(huán)境。
FileInputStream 用于讀取諸如圖像數(shù)據(jù)之類的原始字節(jié)流。要讀取字符流,請(qǐng)考慮使用 FileReader。
FileOutputStream文件輸出流是用于將數(shù)據(jù)寫入 File 或 FileDescriptor 的輸出流。文件是否可用或能否可以被創(chuàng)建取決于基礎(chǔ)平臺(tái)。特別是某些平臺(tái)一次只允許一個(gè) FileOutputStream(或其他文件寫入對(duì)象)打開文件進(jìn)行寫入。在這種情況下,如果所涉及的文件已經(jīng)打開,則此類中的構(gòu)造方法將失敗。
FileOutputStream 用于寫入諸如圖像數(shù)據(jù)之類的原始字節(jié)的流。要寫入字符流,請(qǐng)考慮使用 FileWriter。
字節(jié)流: InputStream OutputStream 需求,想要操作圖片數(shù)據(jù)。這時(shí)就要用到字節(jié)流。 復(fù)制一個(gè)圖片. */ import java.io.*; class FileStream { public static void main(String[] args) throws IOException { readFile_3(); } public static void readFile_3()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); // int num = fis.available(); byte[] buf = new byte[fis.available()];//定義一個(gè)剛剛好的緩沖區(qū)。不用在循環(huán)了。 fis.read(buf); System.out.println(new String(buf)); fis.close(); } public static void readFile_2()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1) { System.out.println(new String(buf,0,len)); } fis.close(); } public static void readFile_1()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); int ch = 0; while((ch=fis.read())!=-1) { System.out.println((char)ch); } fis.close(); } public static void writeFile()throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); fos.write("abcde".getBytes()); fos.close(); } }復(fù)制圖片
/* 復(fù)制一個(gè)圖片 思路: 1,用字節(jié)讀取流對(duì)象和圖片關(guān)聯(lián)。 2,用字節(jié)寫入流對(duì)象創(chuàng)建一個(gè)圖片文件。用于存儲(chǔ)獲取到的圖片數(shù)據(jù)。 3,通過循環(huán)讀寫,完成數(shù)據(jù)的存儲(chǔ)。 4,關(guān)閉資源。 */ import java.io.*; class CopyPic { public static void main(String[] args) { FileOutputStream fos = null; FileInputStream fis = null; try { fos = new FileOutputStream("c:2.bmp"); fis = new FileInputStream("c:1.bmp"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1) { fos.write(buf,0,len); } } catch (IOException e) { throw new RuntimeException("復(fù)制文件失敗"); } finally { try { if(fis!=null) fis.close(); } catch (IOException e) { throw new RuntimeException("讀取關(guān)閉失敗"); } try { if(fos!=null) fos.close(); } catch (IOException e) { throw new RuntimeException("寫入關(guān)閉失敗"); } } } }字節(jié)流的緩沖區(qū)
/* 演示mp3的復(fù)制。通過緩沖區(qū)。 BufferedOutputStream BufferedInputStream */ import java.io.*; class CopyMp3 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); copy_2(); long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); } public static void copy_2()throws IOException { MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:9.mp3")); BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:3.mp3")); int by = 0; //System.out.println("第一個(gè)字節(jié):"+bufis.myRead()); while((by=bufis.myRead())!=-1) { bufos.write(by); } bufos.close(); bufis.myClose(); } //通過字節(jié)流的緩沖區(qū)完成復(fù)制。 public static void copy_1()throws IOException { BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c: