IO流的分類:
* 流向:
* 輸入流 讀取資料
* 輸出流 寫出資料
* 資料型別:
* 位元組流
* 位元組輸入流 讀取資料 InputStream
* 位元組輸出流 寫出資料 OutputStream
* 字符流
* 字符輸入流 讀取資料 Reader
* 字符輸出流 寫出資料 Writer
*
* 注意:一般我們在探討IO流的時候,如果沒有明確說明按哪種分類來說,默認情況下是按照資料型別來分的,
package cn.itcast_01; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /* * IO流的分類: * 流向: * 輸入流 讀取資料 * 輸出流 寫出資料 * 資料型別: * 位元組流 * 位元組輸入流 讀取資料 InputStream * 位元組輸出流 寫出資料 OutputStream * 字符流 * 字符輸入流 讀取資料 Reader * 字符輸出流 寫出資料 Writer * * 注意:一般我們在探討IO流的時候,如果沒有明確說明按哪種分類來說,默認情況下是按照資料型別來分的, * * 需求:我要往一個文本檔案中輸入一句話:"hello,io" * * 分析: * A:這個操作最好是采用字符流來做,但是呢,字符流是在位元組流之后才出現的,所以,今天我先講解位元組流如何操作, * B:由于我是要往檔案中寫一句話,所以我們要采用位元組輸出流, * * 通過上面的分析后我們知道要使用:OutputStream * 但是通過查看API,我們發現該流物件是一個抽象類,不能實體化, * 所以,我們要找一個具體的子類, * 而我們要找的子類是什么名字的呢?這個時候,很簡單,我們回想一下,我們是不是要往檔案中寫東西, * 檔案是哪個單詞:File * 然后用的是位元組輸出流,聯起來就是:FileOutputStream * 注意:每種基類的子類都是以父類名作為后綴名, * XxxOutputStream * XxxInputStream * XxxReader * XxxWriter * 查看FileOutputStream的構造方法: * FileOutputStream(File file) * FileOutputStream(String name) * * 位元組輸出流操作步驟: * A:創建位元組輸出流物件 * B:寫資料 * C:釋放資源 */ public class FileOutputStreamDemo { public static void main(String[] args) throws IOException { // 創建位元組輸出流物件---并直接給出創建的檔案姓名 // FileOutputStream(File file) // File file = new File("fos.txt"); // FileOutputStream fos = new FileOutputStream(file); // FileOutputStream(String name) FileOutputStream fos = new FileOutputStream("fos.txt"); /* * 創建位元組輸出流物件了做了幾件事情: * A:呼叫系統功能去創建檔案 * B:創建fos物件 * C:把fos物件指向這個檔案 */ //寫資料 //public void write(byte[] b) //throws IOException將 b.length 個位元組從指定 byte 陣列寫入此檔案輸出流中, //public byte[] getBytes()使用平臺的默認字符集將此 String 編碼為 byte 序列, // 并將結果存盤到一個新的 byte 陣列中 fos.write("hello,IO".getBytes()); fos.write("java".getBytes()); //釋放資源 //關閉此檔案輸出流并釋放與此流有關的所有系統資源, fos.close(); /* * 為什么一定要close()呢? * A:讓流物件變成垃圾,這樣就可以被垃圾回收器回收了 * B:通知系統去釋放跟該檔案相關的資源 */ //java.io.IOException: Stream Closed //fos.write("java".getBytes()); } }
/*
* 位元組輸出流操作步驟:
* A:創建位元組輸出流物件
* B:呼叫write()方法
* C:釋放資源
*
* public void write(int b):寫一個位元組
* public void write(byte[] b):寫一個位元組陣列
* public void write(byte[] b,int off,int len):寫一個位元組陣列的一部分
*/
1 package cn.itcast_01; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 /* 7 * 位元組輸出流操作步驟: 8 * A:創建位元組輸出流物件 9 * B:呼叫write()方法 10 * C:釋放資源 11 * 12 * public void write(int b):寫一個位元組 13 * public void write(byte[] b):寫一個位元組陣列 14 * public void write(byte[] b,int off,int len):寫一個位元組陣列的一部分 15 */ 16 public class FileOutputStreamDemo2 { 17 public static void main(String[] args) throws IOException { 18 // 創建位元組輸出流物件 19 // OutputStream os = new FileOutputStream("fos2.txt"); // 多型 20 FileOutputStream fos = new FileOutputStream("fos2.txt"); 21 22 // 呼叫write()方法 23 //fos.write(97); //97 -- 底層二進制資料 -- 通過記事本打開 -- 找97對應的字符值 -- a 24 // fos.write(57); 25 // fos.write(55); 26 27 //public void write(byte[] b):寫一個位元組陣列 28 byte[] bys={97,98,99,100,101}; 29 fos.write(bys); 30 31 //public void write(byte[] b,int off,int len):寫一個位元組陣列的一部分 32 fos.write(bys,1,3); 33 34 //釋放資源 35 fos.close(); 36 } 37 }
FileOutPutStream寫出資料實作換行和資料追加寫入
package cn.itcast_01; import java.io.FileOutputStream; import java.io.IOException; /* * 如何實作資料的換行? * 為什么現在沒有換行呢?因為你值寫了位元組資料,并沒有寫入換行符號, * 如何實作呢?寫入換行符號即可唄, * 剛才我們看到了有寫文本檔案打開是可以的,通過windows自帶的那個不行,為什么呢? * 因為不同的系統針對不同的換行符號識別是不一樣的? * windows:\r\n * linux:\n * Mac:\r * 而一些常見的個高級記事本,是可以識別任意換行符號的, * * 如何實作資料的追加寫入? * 用構造方法帶第二個引數是true的情況即可 */ public class FileOutputStreamDemo3 { public static void main(String[] args) throws IOException { // 創建位元組輸出流物件 // FileOutputStream fos = new FileOutputStream("fos3.txt"); // 創建一個向具有指定 name 的檔案中寫入資料的輸出檔案流,如果第二個引數為 true,則將位元組寫入檔案末尾處,而不是寫入檔案開始處, FileOutputStream fos = new FileOutputStream("fos3.txt", true); // 寫資料 for (int x = 0; x < 10; x++) { fos.write(("hello" + x).getBytes()); fos.write("\r\n".getBytes()); } // 釋放資源 fos.close(); } }
FileOutputStream---加入例外處理的位元組輸出流操作
package cn.itcast_01; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /* * 加入例外處理的位元組輸出流操作 */ public class FileOutputStreamDemo4 { public static void main(String[] args) { // 分開做例外處理 // FileOutputStream fos = null; // try { // fos = new FileOutputStream("fos4.txt"); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } // // try { // fos.write("java".getBytes()); // } catch (IOException e) { // e.printStackTrace(); // } // // try { // fos.close(); // } catch (IOException e) { // e.printStackTrace(); // } // 一起做例外處理 // try { // FileOutputStream fos = new FileOutputStream("fos4.txt"); // fos.write("java".getBytes()); // fos.close(); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } // 改進版 // 為了在finally里面能夠看到該物件就必須定義到外面,為了訪問不出問題,還必須給初始化值 FileOutputStream fos = null; try { // fos = new FileOutputStream("z:\\fos4.txt"); fos = new FileOutputStream("fos4.txt"); fos.write("java".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 如果fos不是null,才需要close() if (fos != null) { // 為了保證close()一定會執行,就放到這里了 try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
FileOutputStream----讀取檔案資料
package cn.itcast_02; import java.io.FileInputStream; import java.io.IOException; /* * 位元組輸入流操作步驟: * A:創建位元組輸入流物件 * B:呼叫read()方法讀取資料,并把資料顯示在控制臺 * C:釋放資源 * * 讀取資料的方式: * A:int read():一次讀取一個位元組 * B:int read(byte[] b):一次讀取一個位元組陣列 */ public class FileInputStreamDemo { public static void main(String[] args) throws IOException { // FileInputStream(String name) // FileInputStream fis = new FileInputStream("fis.txt"); FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java"); // // 呼叫read()方法讀取資料,并把資料顯示在控制臺 // // 第一次讀取 // int by = fis.read(); // System.out.println(by); // System.out.println((char) by); // // // 第二次讀取 // by = fis.read(); // System.out.println(by); // System.out.println((char) by); // // // 第三次讀取 // by = fis.read(); // System.out.println(by); // System.out.println((char) by); // // 我們發現代碼的重復度很高,所以我們要用回圈改進 // // 而用回圈,最麻煩的事情是如何控制回圈判斷條件呢? // // 第四次讀取 // by = fis.read(); // System.out.println(by); // // 第五次讀取 // by = fis.read(); // System.out.println(by); // //通過測驗,我們知道如果你讀取的資料是-1,就說明已經讀取到檔案的末尾了 // 用回圈改進 // int by = fis.read(); // while (by != -1) { // System.out.print((char) by); // by = fis.read(); // } // 最終版代碼 int by = 0; // 讀取,賦值,判斷 while ((by = fis.read()) != -1) { System.out.print((char) by); } // 釋放資源 fis.close(); } }
IO(位元組流復制文本檔案案例)
package Day20; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * IO流復制文本檔案 * /* * 復制文本檔案, * * 資料源:從哪里來 * a.txt -- 讀取資料 -- FileInputStream * * 目的地:到哪里去 * b.txt -- 寫資料 -- FileOutputStream * * java.io.FileNotFoundException: a.txt (系統找不到指定的檔案,) * * 這一次復制中文沒有出現任何問題,為什么呢? * 上一次我們出現問題的原因在于我們每次獲取到一個位元組資料,就把該位元組資料轉換為了字符資料,然后輸出到控制臺, * 而這一次呢?確實通過IO流讀取資料,寫到文本檔案,你讀取一個位元組,我就寫入一個位元組,你沒有做任何的轉換, * 它會自己做轉換, */ public class IO4 { public static void main(String[] args) throws IOException { //創建位元組輸入物件---用來讀取檔案資料--- //此時創建物件的同時,系統不會自動創建該檔案---只能自己給出 FileInputStream file = new FileInputStream("zhao.txt"); //創建位元組輸出流物件---用來接受讀取的資料將其寫入 //創建輸出流物件的同時---也會自動創建其檔案 FileOutputStream file1 = new FileOutputStream("zhu.txt"); //將讀出的資料進行寫入 //首先進行讀取資料 int bys = 0; while((bys=file.read())!=-1){ //進行寫入的資料---寫入的資料是讀取的位元組資料 file1.write(bys); } //釋放資源 file1.close();//===輸出流 file.close();//-===輸入流 } }
計算機是如何識別兩個位元組拼接成中文的
package cn.itcast_03; import java.util.Arrays; /* * 計算機是如何識別什么時候該把兩個位元組轉換為一個中文呢? * 在計算機中中文的存盤分兩個位元組: * 第一個位元組肯定是負數, * 第二個位元組常見的是負數,可能有正數,但是沒影響, */ public class StringDemo { public static void main(String[] args) { // String s = "abcde"; // // [97, 98, 99, 100, 101] String s = "我愛你中國"; // [-50, -46, -80, -82, -60, -29, -42, -48, -71, -6] byte[] bys = s.getBytes(); System.out.println(Arrays.toString(bys)); } }
位元組流復制文本檔案(案例2)
package Day20; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; // 需求:把c盤下的a.txt的內容復制到d盤下的b.txt中 public class IO5 { public static void main(String[] args) throws IOException { //首先創建位元組輸入流物件==給出要讀出的檔案==具體的檔案路徑 FileInputStream file = new FileInputStream("C:\\hhh\\a.txt"); //創建位元組輸出流物件====給出要寫入的具體檔案路徑-----此物件也同時可以創建一個檔案 FileOutputStream file1 = new FileOutputStream("D:\\YY\\b.txt"); //將讀出的資料進行寫入 //首先進行讀取資料 //public int read()throws IOException從此輸入流中讀取一個資料位元組---回傳值為-1時,則資料讀取完畢 int bys = 0; while((bys = file.read())!=-1){ //進行資料的寫入 file1.write(bys); } //釋放資源 file1.close(); file1.close(); } }
位元組流復制圖片案例
package Day20; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; //需求:把D:\\螢屏截圖(1).png內容復制到當前專案目錄下的mn.png中 public class IO6 { public static void main(String[] args) throws IOException { //創建位元組輸入流物件----給出絕對路徑 FileInputStream file = new FileInputStream("D:\\螢屏截圖(1).png"); //創建位元組流輸出物件--創建物件的同時也創建其未創建的檔案 FileOutputStream file1 = new FileOutputStream("mn.png"); //讀寫資料 int bys =0; while((bys=file.read())!=-1){ //進行讀資料的寫入 file1.write(bys); } //釋放資源 file.close(); file1.close(); } }
位元組流復制視頻
package cn.itcast_03; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 需求:把e:\\哥有老婆.mp4復制到當前專案目錄下的copy.mp4中 * * 資料源: * e:\\哥有老婆.mp4--讀取資料--FileInputStream * 目的地: * copy.mp4--寫出資料--FileOutputStream */ public class CopyMp4Demo { public static void main(String[] args) throws IOException { // 封裝資料源 FileInputStream fis = new FileInputStream("e:\\哥有老婆.mp4"); // 封裝目的地 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 復制資料 int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } // 釋放資源 fos.close(); fis.close(); } }
FileInputSteram讀取資料一次一個位元組陣列
package Day20; import java.io.FileInputStream; import java.io.IOException; //FileInputStream一次讀取一個位元組陣列 public class IO7 { public static void main(String[] args) throws IOException { //定義一個位元組輸入流物件---給出讀取檔案的具體路徑 FileInputStream file = new FileInputStream("zhao.txt"); //一次讀取一個位元組陣列 byte [] bys = new byte[1024]; int len= 0; //讀入緩沖區的位元組總數,如果因為已經到達檔案末尾而沒有更多的資料,則回傳 -1, while((len=file.read(bys))!=-1){ //讀取時已經給出換行符則不需要給出--------呼叫構造方式此處使用匿名物件 //public String(byte[] bytes,int offset,int length)通過使用平臺的默認字符集解碼指定的 byte 子陣列,構造一個新的 String //bytes - 要解碼為字符的 byt ------offset - 要解碼的第一個 byte 的索引-------length - 要解碼的 byte 數 System.out.print(new String(bys,0,len)); } //釋放資源 file.close(); } }
FileInputSteram讀取資料一次一個位元組陣列(復制文本檔案)
1 package Day20; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 //需求:把c:\\a.txt內容復制到d:\\b.txt中 8 //采用一次復制一個位元組陣列的方式 9 public class IO8 { 10 public static void main(String[] args) throws IOException { 11 //首先定義一個位元組輸入流物件----資料源 12 FileInputStream file = new FileInputStream("C:\\hhhh\\a.txt"); 13 14 //定義一個位元組輸出流物件----目標源 15 FileOutputStream file1 = new FileOutputStream("D:\\YY\\b.txt"); 16 17 18 //定義一個位元組陣列 19 byte [] bys = new byte[1024]; 20 //初始化檔案寫入位置為0 21 int len=0; 22 //public int read(byte[] b)throws IOException 23 //從此輸入流中將最多 b.length 個位元組的資料讀入一個 byte 陣列中 24 //讀入緩沖區的位元組總數,如果因為已經到達檔案末尾而沒有更多的資料,則回傳 -1, 25 while((len=file.read(bys))!=-1){ 26 //public void write(byte[] b,int off,int len) 27 //將指定 byte 陣列中從偏移量 off 開始的 len 個位元組寫入此檔案輸出流 28 file1.write(bys,0,len); 29 } 30 31 //釋放記憶體 32 file1.close(); 33 file.close(); 34 35 } 36 }
BufferedOutputStream---* 寫資料:BufferedOutputStream
通過定義陣列的方式確實比以前一次讀取一個位元組的方式快很多,所以,看來有一個緩沖區還是非常好的,
* 既然是這樣的話,那么,java開始在設計的時候,它也考慮到了這個問題,就專門提供了帶緩沖區的位元組類,
* 這種類被稱為:緩沖區類(高效類)
* 寫資料:BufferedOutputStream
* 讀資料:BufferedInputStream
*
* 構造方法可以指定緩沖區的大小,但是我們一般用不上,因為默認緩沖區大小就足夠了,
*
* 為什么不傳遞一個具體的檔案或者檔案路徑,而是傳遞一個OutputStream物件呢?
* 原因很簡單,位元組緩沖區流僅僅提供緩沖區,為高效而設計的,但是呢,真正的讀寫操作還得靠基本的流物件實作,
package cn.itcast_05; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 通過定義陣列的方式確實比以前一次讀取一個位元組的方式快很多,所以,看來有一個緩沖區還是非常好的, * 既然是這樣的話,那么,java開始在設計的時候,它也考慮到了這個問題,就專門提供了帶緩沖區的位元組類, * 這種類被稱為:緩沖區類(高效類) * 寫資料:BufferedOutputStream * 讀資料:BufferedInputStream * * 構造方法可以指定緩沖區的大小,但是我們一般用不上,因為默認緩沖區大小就足夠了, * * 為什么不傳遞一個具體的檔案或者檔案路徑,而是傳遞一個OutputStream物件呢? * 原因很簡單,位元組緩沖區流僅僅提供緩沖區,為高效而設計的,但是呢,真正的讀寫操作還得靠基本的流物件實作, */ public class BufferedOutputStreamDemo { public static void main(String[] args) throws IOException { // BufferedOutputStream(OutputStream out) // FileOutputStream fos = new FileOutputStream("bos.txt"); // BufferedOutputStream bos = new BufferedOutputStream(fos); // 簡單寫法 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("bos.txt")); // 寫資料 bos.write("hello".getBytes()); // 釋放資源 bos.close(); } }
自寫版
package Day20; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; /* * BufferOutputStream---* 寫資料:BufferedOutputStream * * * */ public class IO9 { public static void main(String[] args) throws IOException { BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream("qing.txt")); //寫入資料---將寫入的字串---轉化為位元組 file.write("hello\n".getBytes()); file.write("hasdiasjbcdajscnasc".getBytes()); //釋放資源 file.close(); } }
BufferedInputStream----讀資料:BufferedInputStream
package cn.itcast_05; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; /* * 注意:雖然我們有兩種方式可以讀取,但是,請注意,這兩種方式針對同一個物件在一個代碼中只能使用一個, */ public class BufferedInputStreamDemo { public static void main(String[] args) throws IOException { // BufferedInputStream(InputStream in) BufferedInputStream bis = new BufferedInputStream(new FileInputStream( "bos.txt")); // 讀取資料 // int by = 0; // while ((by = bis.read()) != -1) { // System.out.print((char) by); // } // System.out.println("---------"); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { System.out.print(new String(bys, 0, len)); } // 釋放資源 bis.close(); } }
自寫版
package Day20; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; //BufferInputStream----讀資料:BufferedInputStream public class IO10 { public static void main(String[] args) throws IOException { //創建位元組緩沖區類 BufferedInputStream file = new BufferedInputStream(new FileInputStream("qing.txt")); // // //進行讀資料 // //方式一---一次讀取一個位元組 // int by =0; // while((by=file.read())!=-1){ // //將讀取的位元組--轉換為字符型別進行輸出 // System.out.println((char)by); // } // // //釋放資源 // file.close(); //進行讀資料 //方式二---一次讀取一個位元組陣列 byte [] bys = new byte[1024]; int len =0; while((len=file.read(bys))!=-1){ //public String(byte[] bytes,int offset,int length)通過使用平臺的默認字符集解碼指定的 byte 子陣列, // 構造一個新的 String System.out.println(new String(bys,0,len)); } //釋放資源 file.close(); } }
位元組流四種方式復制速度對比
package cn.itcast_06; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 需求:把e:\\哥有老婆.mp4復制到當前專案目錄下的copy.mp4中 * * 位元組流四種方式復制檔案: * 基本位元組流一次讀寫一個位元組: 共耗時:117235毫秒 * 基本位元組流一次讀寫一個位元組陣列: 共耗時:156毫秒 * 高效位元組流一次讀寫一個位元組: 共耗時:1141毫秒 * 高效位元組流一次讀寫一個位元組陣列: 共耗時:47毫秒 */ public class CopyMp4Demo { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); // method1("e:\\哥有老婆.mp4", "copy1.mp4"); // method2("e:\\哥有老婆.mp4", "copy2.mp4"); // method3("e:\\哥有老婆.mp4", "copy3.mp4"); method4("e:\\哥有老婆.mp4", "copy4.mp4"); long end = System.currentTimeMillis(); System.out.println("共耗時:" + (end - start) + "毫秒"); } // 高效位元組流一次讀寫一個位元組陣列: public static void method4(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( srcString)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destString)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); bis.close(); } // 高效位元組流一次讀寫一個位元組: public static void method3(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( srcString)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destString)); int by = 0; while ((by = bis.read()) != -1) { bos.write(by); } bos.close(); bis.close(); } // 基本位元組流一次讀寫一個位元組陣列 public static void method2(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { fos.write(bys, 0, len); } fos.close(); fis.close(); } // 基本位元組流一次讀寫一個位元組 public static void method1(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } fos.close(); fis.close(); } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/454614.html
標籤:Java
