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