Java IO流
IO流是用來處理設備之間的數據傳輸的,Java對數據的操作都是使用流的方式處理的,而且Java將處理流的操作封裝成IO流對象了。
一、IO流的分類
流按照操作的數據分為:字節流、字符流
流按照流的方向分為:輸入流、輸出流
二、字節流:
inputString------此抽象類是表示字節輸入流的所有類的超類。
inputStream提供的方法
inputStream是輸入流,是應用程序讀取數據的方式,而read()方法就是InputStream讀取數據的方式
從API中可以看到,read()方法一共有三種
(1)int b=in.read();
從輸入流中讀取數據的下一個字節,返回0到255範圍內的int字節值,如果讀到流的末尾就返回-1
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\\learnJava\\hello.txt"); int by=0; while((by=in.read())!=-1){ //判斷是否讀到流的末尾 System.out.println(by); } in.close(); //使用完,記得關閉 }
(2)public int read (byte[] buf)
從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 buf中,將讀取的第一個字節存儲在元素 buf[0]
中,下一個存儲在 buf[1]
中,依次類推。讀取的字節數最多等於 b
的長度。返回的是實際讀取的字節個數,如果讀到流的末尾依舊返回-1;
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\\learnJava\\hello.txt"); //創建流對象,如果文件不存在拋出FileNotFoundException/*int by=0;*/ byte [] buf=new byte[1024]; int len=0; //記錄讀取的字節個數 while((len=in.read(buf))!=-1){ //判斷是否讀到流的末尾 System.out.println(new String(buf,0,len)); } in.close(); //使用完,記得關閉 }
(3)public int read(byte[] buf, int start, int len)
將輸入流中長度不超過len的數據字節讀入數組,從數組的start位置開始存儲,也就是說將讀取的第一個字節存儲在元素 b[start]
中,下一個存儲在 b[start+1]
中,依次類推。讀取的字節數最多等於 len
。返回值仍然是讀取的字節個數,如果讀到流的末尾則返回-1.
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\\learnJava\\hello.txt"); //創建流對象,如果文件不存在拋出FileNotFoundException /*int by=0;*/ byte [] buf=new byte[1024]; int len=0; //記錄讀取的字節個數 while((len=in.read(buf,0,5))!=-1){ //判斷是否讀到流的末尾 System.out.println(new String(buf,0,len)); } in.close(); //使用完,記得關閉 }
OuputStream-------此抽象類是表示輸出字節流的所有類的超類
OutputStream提供的方法
outputstream是輸出流,提供了應用程序寫出數據的方式,提供了三種write()方法
(1)public abstract void write(int b)
將指定的字節寫入次輸出流中,即將參數b的低八位寫入到輸出流,b的高24位將被忽略
OutputStream os=new FileOutputStream("E:\\learnJava\\hello.txt"); int b=100; os.write(b); os.close();
(2)public void write(byte[] b)
將b.length個字節從指定的byte數組寫入此輸入流,即將數組b中的所有字節一次寫入輸出流中。
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\\learnJava\\1.txt"); OutputStream os=new FileOutputStream("E:\\learnJava\\hello.txt"); int b=100; byte [] buf=new byte[in.available()]; int len=0; while((len=in.read(buf))!=-1){ //將輸入流保存到byte數組中 os.write(buf); //將byte數組中的字節寫入到輸出流 } in.close(); os.close(); }
其實上面的例子也實現了文件的復制功能
(3)public void write(byte[] b, int off, int len)
將制定byte數組中從第off個字節開始,len個字節寫入此輸出流,元素 b[off]
是此操作寫入的第一個字節,b[off+len-1]
是此操作寫入的最後一個字節。
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\\learnJava\\1.txt"); OutputStream os=new FileOutputStream("E:\\learnJava\\hello.txt"); int b=100; byte [] buf=new byte[in.available()]; int len=0; while((len=in.read(buf,0,5))!=-1){ //將輸入流保存到byte數組中 os.write(buf,0,5); //將byte數組中的字節寫入到輸出流 } in.close(); os.close(); }
這種方法和上一種方法一樣,只是限制了讀取的字節個數
(4)public void flush() 方法
刷新此輸出流並強制寫出所有緩沖的輸出字節。也就是輸出流字節傳給操作系統,具體實現寫入磁盤的操作有操作系統實現。
(5)public void close()
關閉此輸出流並釋放與此流有關的所有系統資源
inputSteam和OutputStream的子類
(1)FileInputStream和FileOutputStream
FileInputStream
從文件系統中的某個文件中獲得輸入字節。哪些文件可用取決於主機環境。 FileInputStream
用於讀取諸如圖像數據之類的原始字節流。
FileOutputStream文件輸出流是用於將數據寫入 File
或 FileDescriptor
的輸出流。文件是否可用或能否可以被創建取決於基礎平臺。FileOutputStream
用於寫入諸如圖像數據之類的原始字節的流。
其實上面基本都是以FileinputStream和FileOutStream為例,此處在貼一個復制圖片的例子,實現方法都是一樣的。
public static void main(String[] args){ FileInputStream fin=null; FileOutputStream fos=null; byte []buf=new byte[1024]; int len=0; try { fin=new FileInputStream("E:\\learnJava\\io流.jpg"); fos=new FileOutputStream("E:\\learnJava\\temp.jpg"); while((len=fin.read(buf))!=-1){ fos.write(buf); } } catch (IOException e) { e.printStackTrace(); }finally { try { fin.close(); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(2)BufferedInputStream和BufferedOutputStream
FileInputStream和FileOutputStream是不帶緩沖區的,每次讀取寫入時都需要我們自己寫一個byte數組充當緩沖區,而BufferedInputStream和BufferedOutputStream是實現緩沖的輸入輸出流
BufferedInputStream
在創建 BufferedInputStream
時,會創建一個內部緩沖區數組。在讀取或跳過流中的字節時,可根據需要從包含的輸入流再次填充該內部緩沖區,一次填充多個字節。
BufferedOutputStream該類實現緩沖的輸出流。
public static void main(String[] args){ FileInputStream fin=null; FileOutputStream fos=null; try { fin = new FileInputStream("E:\\learnJava\\風吹麥浪.mp3"); fos=new FileOutputStream("E:\\learnJava\\風吹麥浪_副本.mp3"); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } BufferedInputStream bin=new BufferedInputStream(fin); BufferedOutputStream bos=new BufferedOutputStream(fos); int len=0; try { while((len=bin.read())!=-1){ bos.write(len); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { bin.close(); bos.close(); fin.close(); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(3)DataInputStream和DataOutputStream
DataInputStream數據輸入流允許應用程序以與機器無關方式從底層輸入流中讀取基本 Java 數據類型。應用程序可以使用數據輸出流寫入稍後由數據輸入流讀取的數據。
DataOutputStream數據輸出流允許應用程序以適當方式將基本 Java 數據類型寫入輸出流中。然後,應用程序可以使用數據輸入流將數據讀入。
public static void main(String[] args) throws IOException{//規避一下IO異常 //輸出 DataOutputStream dos=new DataOutputStream(new FileOutputStream("E:\\learnJava\\dataOs.txt")); dos.writeInt(100); dos.writeLong(10l); dos.writeInt(-100); dos.writeChar(‘A‘); dos.writeUTF("中國");//采用UTF-8編碼 dos.writeChars("中國");//采用utf-16be編碼 //讀取 DataInputStream din=new DataInputStream(new FileInputStream("E:\\learnJava\\dataOs.txt")); System.out.println(din.readInt()); //讀取存入的第一個int 100 System.out.println(din.readLong());//讀取long數據 System.out.println(din.readInt()); System.out.println(din.readChar()); //讀取char System.out.println(din.readUTF()); //讀取UTF }
三、字符流
字符流操作的是文本文件,是文本(char)序列按照某種編碼方案(unt-8,utf-16be,gbk)序列化而成的文件。
Reader-------用於讀取字符流的抽象類
Reader提供 的方法
(1)public int read() -----讀取單個字符
返回值是作為整數讀取的字符,範圍在 0 到 65535 之間 (0x00-0xffff),如果已到達流的末尾,則返回 -1
public static void main(String[] args) throws IOException{//規避一下IO異常 Reader reader=new FileReader("E:\\learnJava\\HelloReader.txt");//保證文件存在,否則拋出FileNotFoundException int ch=0; while((ch=reader.read())!=-1){ System.out.println((char)ch); } reader.close(); }
(2)public int read(char[] cbuf) ----將字符讀入數組
返回值為讀取的字符數,如果已到達流的末尾,則返回 -1 ;
public static void main(String[] args) throws IOException{//規避一下IO異常 Reader reader=new FileReader("E:\\learnJava\\HelloReader.txt");//保證文件存在,否則拋出FileNotFoundException char [] buf=new char[1024]; int len=0; while((len=reader.read(buf))!=-1){ System.out.println(new String(buf, 0, len)); } reader.close(); }
(3)public abstract int read(char[] cbuf, int off, int len) ----將字符讀入數組的某一部分
Writer------寫入字符流的抽象類
writer提供的方法
public static void main(String[] args) throws IOException{//規避一下IO異常 Writer writer=new FileWriter("E:\\learnJava\\HelloWriter.txt"); writer.write(100); //寫入一個字符 writer.write("你好,Java");//寫入一個字符串 char [] buf=new char[]{‘A‘,‘B‘,‘中‘,‘國‘}; writer.write(buf, 0, buf.length); //寫入一個字符數組 String str=new String("使用Writer"); writer.write(str, 2, 6); writer.close(); }
reader和writer的子類
(1)InputStreamReader和OutputStreamWriter------實現字符流和字節流的轉換
InputStreamReader 是字節流通向字符流的橋梁:每次調用 InputStreamReader 中的一個 read() 方法都會導致從底層輸入流讀取一個或多個字節。要啟用從字節到字符的有效轉換,可以提前從底層流讀取更多的字節,使其超過滿足當前讀取操作所需的字節。
public static void main(String[] args) throws IOException{//規避一下IO異常 InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\learnJava\\繞口令.txt"),"gbk");//指出文件的編碼方式 char [] buf=new char[1024]; int len=0; while((len=isr.read(buf, 0, buf.length))!=-1){ System.out.println(new String(buf,0,len)); } isr.close(); }
其他方法:
OutputStreamWriter 是字符流通向字節流的橋梁,每次調用 write() 方法都會導致在給定字符(或字符集)上調用編碼轉換器。在寫入底層輸出流之前,得到的這些字節將在緩沖區中累積。可以指定此緩沖區的大小,不過,默認的緩沖區對多數用途來說已足夠大。註意,傳遞給 write() 方法的字符沒有緩沖。
實例:文件的復制
public static void main(String[] args) throws IOException{//規避一下IO異常 InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\learnJava\\繞口令.txt"),"gbk");//指出文件的編碼方式 /*創建一個FileWriter對象,該對象一被初始化,就必須要明確被操作的文件. 而且該文件會被創建到指定目錄下,如果該目錄下已有同名的文件,將被覆蓋。 其實該步就是明確數據要存放的目的地*/ OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\learnJava\\繞口令_副本.txt"), "gbk"); char [] buf=new char[1024]; int len=0; while((len=isr.read(buf, 0, buf.length))!=-1){ osw.write(buf, 0, len); // 寫入字符數組的某一部分。 } isr.close(); osw.close(); }
其他方法
(2)FileReader和FileWriter------直接操作文件
public static void main(String[] args) throws IOException{//規避一下IO異常 FileReader fReader=new FileReader("E:\\learnJava\\笑話大全.txt");//直接寫文件路徑,或者文件對象 FileWriter fWriter=new FileWriter("E:\\learnJava\\笑話大全_副本.txt");//輸出到文件,沒有則創建新的,有則覆蓋,沒有編碼方式(不同編碼方式會有亂碼) int len=0; char [] buf=new char[1024]; while((len=fReader.read(buf,0,buf.length))!=-1){ fWriter.write(buf,0,len); fWriter.flush(); } fReader.close(); fWriter.close(); }
(3)BufferedReader和BufferedWriter-----字符流的過濾器
BufferedReader:從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。
方法public String readLine() 實現讀取一個文本行。通過下列字符之一即可認為某行已終止:換行 (‘\n‘)、回車 (‘\r‘) 或回車後直接跟著換行。
BufferedWriter將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數組和字符串的高效寫入。
public static void main(String[] args) throws IOException{//規避一下IO異常 //文件的讀操作 //使用BufferedReader提高讀的效率 BufferedReader bReader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\\learnJava\\笑話大全.txt"),"gbk")); //文件輸出 BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\learnJava\\笑話大全_副本2.txt"),"gbk")); String line; while((line=bReader.readLine())!=null){ /*System.out.println(line); //一次讀一行,line並沒有實現換行*/ bWriter.write(line); bWriter.newLine();//實現換行 bWriter.flush(); } bReader.close(); bWriter.close(); }
其中BufferedWriter可以使用PrintWrite代替,會更方便
public static void main(String[] args) throws IOException{//規避一下IO異常 //文件的讀操作 //使用BufferedReader提高讀的效率 BufferedReader bReader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\\learnJava\\笑話大全.txt"),"gbk")); //文件輸出 /* BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\learnJava\\笑話大全_副本2.txt"),"gbk"));*/ PrintWriter pWriter=new PrintWriter("E:\\learnJava\\笑話大全_副本3.txt"); String line; while((line=bReader.readLine())!=null){ /*System.out.println(line); //一次讀一行,line並沒有實現換行*/ /* bWriter.write(line); bWriter.newLine();//實現換行 bWriter.flush();*/ pWriter.println(line); //println自帶換行 pWriter.flush(); } bReader.close(); /* bWriter.close();*/ }
Java IO流