| InputStream 所有輸入字節(jié)流的基類 抽象類 ————| FileInputStream 讀取文件數(shù)據(jù)的輸入字節(jié)流
使用FileInputStream讀取文件數(shù)據(jù)的步驟: 1. 找到目標(biāo)文件 2. 建立數(shù)據(jù)的輸入通道。 3. 讀取文件中的數(shù)據(jù)。 4. 關(guān)閉 資源.
注意點(diǎn):read()方法返回的值講解:1、返回值為原本數(shù)據(jù)數(shù)據(jù):read() 讀取一個(gè)字節(jié)的數(shù)據(jù),把讀取的數(shù)據(jù)返回。如:int content = fileInputStream.read(); 2、返回值為字節(jié)數(shù)據(jù)的個(gè)數(shù)如果使用read讀取數(shù)據(jù)傳入字節(jié)數(shù)組,那么數(shù)據(jù)是存儲(chǔ)到字節(jié)數(shù)組中的,而這時(shí)候read方法的返回值是表示的是本次讀取了幾個(gè)字節(jié)數(shù)據(jù)到字節(jié)數(shù)組中。while((length = fileInputStream.read(buf))!=-1){ // read方法如果讀取到了文件的末尾,那么會(huì)返回-1表示。 System.out.PRint(new String(buf,0,length));}public class inputDemo1 { public static void main(String[] args) throws IOException { } private static void importDemo1() throws FileNotFoundException, IOException { //找到目標(biāo)文件 File file = new File("/Users/liyunxiang/Desktop/1.txt"); System.out.println(file.exists()); //判斷文件是否存在 //建立數(shù)據(jù)輸入通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩沖數(shù)組配合循環(huán)讀取文件的數(shù)據(jù)。 int length = 0; //保存每次讀取到的字節(jié)個(gè)數(shù)。 //存儲(chǔ)讀取到的數(shù)據(jù) 緩沖數(shù)組 的長度一般是1024的倍數(shù),因?yàn)榕c計(jì)算機(jī)的處理單位。 理論上緩沖數(shù)組越大,效率越高 byte[] buf = new byte[1024]; // 如果使用read讀取數(shù)據(jù)傳入字節(jié)數(shù)組,那么數(shù)據(jù)是存儲(chǔ)到字節(jié)數(shù)組中的, //而這時(shí)候read方法的返回值是表示的是本次讀取了幾個(gè)字節(jié)數(shù)據(jù)到字節(jié)數(shù)組中。 while((length = fileInputStream.read(buf))!=-1){ // read方法如果讀取到了文件的末尾,那么會(huì)返回-1表示。 System.out.print(new String(buf,0,length)); } //關(guān)閉資源 fileInputStream.close(); } }問題: 讀取完一個(gè)文件的數(shù)據(jù)的時(shí)候,我不關(guān)閉資源有什么影響? 答案: 資源文件一旦 使用完畢應(yīng)該馬上釋放,否則其他的程序無法對該資源文件進(jìn)行其他 的操作。
輸出字節(jié)流:
——–| OutputStream 是所有輸出字節(jié)流 的父類。 抽象類 ———–| FileOutStream 向文件輸出數(shù)據(jù)的輸出字節(jié)流。
FileOutputStream如何使用呢? 1. 找到目標(biāo)文件 2. 建立數(shù)據(jù)的輸出通道。 3. 把數(shù)據(jù)轉(zhuǎn)換成字節(jié)數(shù)組寫出。 4. 關(guān)閉資源
FileOutputStream要注意的細(xì)節(jié): 1. 使用FileOutputStream 的時(shí)候,如果目標(biāo)文件不存在,那么會(huì)自動(dòng)創(chuàng)建目標(biāo)文件對象。 2. 使用FileOutputStream寫數(shù)據(jù)的時(shí)候,如果目標(biāo)文件已經(jīng)存在,那么會(huì)先清空目標(biāo)文件中的數(shù)據(jù),然后再寫入數(shù)據(jù)。 3.使用FileOutputStream寫數(shù)據(jù)的時(shí)候, 如果目標(biāo)文件已經(jīng)存在,需要在原來數(shù)據(jù)基礎(chǔ)上追加數(shù)據(jù)的時(shí)候應(yīng)該使用new FileOutputStream(file,true)構(gòu)造函數(shù),第二參數(shù)為true。 4.使用FileOutputStream的write方法寫數(shù)據(jù)的時(shí)候,雖然接收的是一個(gè)int類型的數(shù)據(jù),但是真正寫出的只是一個(gè)字節(jié)的數(shù)據(jù),只是 把低八位的二進(jìn)制數(shù)據(jù)寫出,其他二十四位數(shù)據(jù)全部丟棄。 00000000-000000000-00000001-11111111 511 11111111---> -1 public class OutPutDemo { public static void main(String[] args) throws IOException { //找到目標(biāo)文件 File file = new File("/Users/liyunxiang/Desktop/1.txt"); //建立數(shù)據(jù)輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //每次只能寫一個(gè)字節(jié)的數(shù)據(jù)出去。 fileOutputStream.write('h'); //使用字節(jié)數(shù)組把數(shù)據(jù)寫出。 String data = "hello world"; fileOutputStream.write(data.getBytes()); //使用字節(jié)數(shù)組把數(shù)據(jù)寫出。,0 從字節(jié)數(shù)組的指定索引值開始寫, 2:寫出兩個(gè)字節(jié)。 byte[] buf = data.getBytes(); fileOutputStream.write(buf,0,3); //關(guān)閉資源 fileOutputStream.close(); }}需求: 利用輸入輸出流拷貝一張圖片
public class CopyImage { public static void main(String[] args) throws IOException { //找到目標(biāo)文件 File inFile = new File("F://美女//1.jpg"); File destFile = new File("E://1.jpg"); //建立數(shù)據(jù)的輸入輸出通道 FileInputStream fileInputStream = new FileInputStream(inFile); FileOutputStream fileOutputStream = new FileOutputStream(destFile); //追加數(shù)據(jù).... //每新創(chuàng)建一個(gè)FileOutputStream的時(shí)候,默認(rèn)情況下FileOutputStream 的指針是指向了文件的開始的位置。 每寫出一次,指向都會(huì)出現(xiàn)相應(yīng)移動(dòng)。 //建立緩沖數(shù)據(jù),邊讀邊寫 byte[] buf = new byte[1024]; int length = 0 ; while((length = fileInputStream.read(buf))!=-1){ //最后一次只剩下了824個(gè)字節(jié) fileOutputStream.write(buf,0,length); //寫出很多次數(shù)據(jù),所以就必須要追加。 } //關(guān)閉資源 原則: 先開后關(guān),后開先關(guān)。 fileOutputStream.close(); fileInputStream.close(); }}緩沖輸入字節(jié)流
我們清楚讀取文件數(shù)據(jù)使用緩沖數(shù)組讀取效率更高,sun也知道使用緩沖數(shù)組讀取效率更高,那么 這時(shí)候sun給我們提供了一個(gè)——緩沖輸入字節(jié)流對象,讓我們可以更高效率讀取文件。
輸入字節(jié)流體系: —-| InputStream 輸入字節(jié)流的基類。 抽象 ———-| FileInputStream 讀取文件數(shù)據(jù)的輸入字節(jié)流 ———-| BufferedInputStream 緩沖輸入字節(jié)流 緩沖輸入字節(jié)流的出現(xiàn)主要是為了提高讀取文件數(shù)據(jù)的效率。 其實(shí)該類內(nèi)部只不過是維護(hù)了一個(gè)8kb的字節(jié)數(shù)組而已。
注意: 凡是緩沖流都不具備讀寫文件的能力。
使用BufferedInputStream的步驟 : 1. 找到目標(biāo)文件。 2. 建立數(shù)據(jù) 的輸入通道 3. 建立緩沖 輸入字節(jié)流流 4. 關(guān)閉資源
public class Demo1 { public static void main(String[] args) throws IOException { readTest2(); } public static void readTest2() throws IOException{ //找到目標(biāo)文件 File file = new File("F://a.txt"); FileInputStream fileInputStream= new FileInputStream(file); BufferedInputStream bufferedInputStream= new BufferedInputStream(fileInputStream); bufferedInputStream.read(); FileOutputStream fileOutputStream= new FileOutputStream(file); BufferedOutputStream bufferedOutputStream= new BufferedOutputStream(fileOutputStream); fileOutputStream.write(null); //讀取文件數(shù)據(jù) int content = 0 ; //疑問二:BufferedInputStream出現(xiàn) 的目的是了提高讀取文件的效率,但是BufferedInputStream的read方法每次讀取一個(gè)字節(jié)的數(shù)據(jù) //而FileInputStreram每次也是讀取一個(gè)字節(jié)的數(shù)據(jù),那么BufferedInputStream效率高從何而來? while((content = fileInputStream.read())!=-1){ System.out.print((char)content); } //關(guān)閉資源 bufferedInputStream.close();//調(diào)用BufferedInputStream的close方法實(shí)際上關(guān)閉的是FileinputStream. } //讀取文件的時(shí)候我們都是使用緩沖數(shù)組讀取。效率會(huì)更加高 public static void readTest() throws IOException{ File file = new File("/Users/liyunxiang/Desktop/1.txt"); //建立數(shù)組通道 FileInputStream fileInputStream = new FileInputStream(file); //建立緩沖數(shù)組讀取數(shù)據(jù) byte[] buf = new byte[1024*8]; int length = 0; while((length = fileInputStream.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } //關(guān)閉資源 fileInputStream.close(); }}輸出字節(jié)流
——–| OutputStream 所有輸出字節(jié)流的基類 抽象類 ————| FileOutputStream 向文件 輸出數(shù)據(jù) 的輸出字節(jié)流 ————| Bufferedoutputstream 緩沖輸出字節(jié)流 BufferedOutputStream出現(xiàn)的目的是為了提高寫數(shù)據(jù)的效率。 內(nèi)部也是維護(hù)了一個(gè)8kb的字節(jié)數(shù)組而已。
使用BufferedOutputStream的步驟: 1. 找到目標(biāo)文件 2. 建立數(shù)據(jù)的輸出通道
BufferedOutputStream 要注意的細(xì)節(jié) 1. 使用BufferedOutStream寫數(shù)據(jù)的時(shí)候,它的write方法是是先把數(shù)據(jù)寫到它內(nèi)部維護(hù)的字節(jié)數(shù)組中。 2. 使用BufferedOutStream寫數(shù)據(jù)的時(shí)候,它的write方法是是先把數(shù)據(jù)寫到它內(nèi)部維護(hù)的字節(jié)數(shù)組中,如果需要把數(shù)據(jù)真正的寫到硬盤上面,需要 調(diào)用flush方法或者是close方法、 或者是內(nèi)部維護(hù)的字節(jié)數(shù)組已經(jīng)填滿數(shù)據(jù)的時(shí)候。
public class Demo2 { public static void main(String[] args) throws IOException { //找到目標(biāo)文件 File file = new File("/Users/liyunxiang/Desktop/1.txt"); //建立數(shù)據(jù)的輸出通道 FileOutputStream fileOutputStream = new FileOutputStream(file); //建立緩沖輸出字節(jié)流對象 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //把數(shù)據(jù)寫出 bufferedOutputStream.write("hello world".getBytes()); //把緩沖數(shù)組中內(nèi)部的數(shù)據(jù)寫到硬盤上面。 //bufferedOutputStream.flush(); bufferedOutputStream.close(); }}使用緩沖輸入輸出字節(jié)流拷貝一個(gè)圖片
public class CopyImage { public static void main(String[] args) throws IOException { //找到目標(biāo)文件 File inFile = new File("F://美女//1.jpg"); File outFile = new File("E://1.jpg"); //建立數(shù)據(jù)輸入輸出通道 FileInputStream fileInputStream = new FileInputStream(inFile); FileOutputStream fileOutputStream = new FileOutputStream(outFile); //建立緩沖輸入輸出流 BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //邊讀邊寫 int content = 0; // int length = bufferedInputStream.read(buf); 如果傳入了緩沖數(shù)組,內(nèi)容是存儲(chǔ)到緩沖數(shù)組中,返回值是存儲(chǔ)到緩沖數(shù)組中的字節(jié)個(gè)數(shù)。 while((content = bufferedInputStream.read())!=-1){ // 如果使用read方法沒有傳入緩沖數(shù)組,那么返回值是讀取到的內(nèi)容。 bufferedOutputStream.write(content);// bufferedOutputStream.flush(); } //關(guān)閉資源 bufferedInputStream.close(); bufferedOutputStream.close(); }}IO異常 的處理
package cn.itcast.exception;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import javax.management.RuntimeErrorException;/* IO異常 的處理 */public class Demo1 { public static void main(String[] args) { // readTest(); copyImage(); } // 拷貝圖片 public static void copyImage() { FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { // 找到目標(biāo)文件 File inFile = new File("F://美女//1.jpg"); File outFile = new File("E://1.jpg"); // 建立輸入輸出通道 fileInputStream = new FileInputStream(inFile); fileOutputStream = new FileOutputStream(outFile); // 建立緩沖數(shù)組,邊讀邊寫 byte[] buf = new byte[1024]; int length = 0; while ((length = fileInputStream.read(buf)) != -1) { fileOutputStream.write(buf, 0, length); } } catch (IOException e) { System.out.println("拷貝圖片出錯(cuò)..."); throw new RuntimeException(e); } finally { // 關(guān)閉資源 try { if (fileOutputStream != null) { fileOutputStream.close(); System.out.println("關(guān)閉輸出流對象成功..."); } } catch (IOException e) { System.out.println("關(guān)閉輸出流資源失敗..."); throw new RuntimeException(e); } finally { if (fileInputStream != null) { try { fileInputStream.close(); System.out.println("關(guān)閉輸入流對象成功..."); } catch (IOException e) { System.out.println("關(guān)閉輸入流對象失敗..."); throw new RuntimeException(e); } } } } } public static void readTest() { FileInputStream fileInputStream = null; try { // 找到目標(biāo)文件 File file = new File("F://aaaaa.txt"); // 建立數(shù)據(jù)輸入通道 fileInputStream = new FileInputStream(file); // 建立緩沖數(shù)組讀取數(shù)據(jù) byte[] buf = new byte[1024]; int length = 0; while ((length = fileInputStream.read(buf)) != -1) { System.out.print(new String(buf, 0, length)); } } catch (IOException e) { /* * //處理的代碼... 首先你要阻止后面的代碼執(zhí)行,而且要需要通知調(diào)用者這里出錯(cuò)了... throw new * RuntimeException(e); * //把IOException傳遞給RuntimeException包裝一層,然后再拋出,這樣子做的目的是 * 為了讓調(diào)用者使用變得更加靈活。 */ System.out.println("讀取文件資源出錯(cuò)...."); throw new RuntimeException(e); } finally { try { if (fileInputStream != null) { fileInputStream.close(); System.out.println("關(guān)閉資源成功..."); } } catch (IOException e) { System.out.println("關(guān)閉資源失敗..."); throw new RuntimeException(e); } } }}輸入字符流
字節(jié)流:字節(jié)流讀取的是文件中的二進(jìn)制數(shù)據(jù),讀到的數(shù)據(jù)并不會(huì)幫你轉(zhuǎn)換成你看得懂的字符。
字符流: 字符流會(huì)把讀取到的二進(jìn)制的數(shù)據(jù)進(jìn)行對應(yīng) 的編碼與解碼工作。 字符流 = 字節(jié)流 + 編碼(解碼)
輸入字符流: ———-| Reader 輸入字符流的基類 抽象類 ————-| FileReader 讀取文件的輸入字符流。
FileReader的用法: 1. 找到目標(biāo)文件 2. 建立數(shù)據(jù)的輸入通道 3. 讀取數(shù)據(jù) 4. 關(guān)閉資源
public class Demo2 { public static void main(String[] args) throws IOException { readTest2(); } //使用緩沖字符數(shù)組讀取文件。 public static void readTest2() throws IOException{ //找到目標(biāo)文件 File file = new File(“/Users/liyunxiang/Desktop/1.txt“); // 建立數(shù)據(jù)的輸入通道 FileReader fileReader = new FileReader(file); //建立緩沖字符數(shù)組讀取文件數(shù)據(jù) char[] buf = new char[1024]; int length = 0 ; while((length = fileReader.read(buf))!=-1){ System.out.print(new String(buf,0,length)); } } public static void readTest1() throws IOException{ //找到目標(biāo)文件 File file = new File("/Users/liyunxiang/Desktop/1.txt"); //建立數(shù)據(jù)的輸入通道 FileReader fileReader = new FileReader(file); int content = 0 ; while((content = fileReader.read())!=-1){ //每次只會(huì)讀取一個(gè)字符,效率低。 System.out.print((char)content); } //關(guān)閉資源 fileReader.close(); }}輸出字符流
輸出字符流:
——| Writer 輸出字符流的基類。 抽象類 ———–| FileWriter 向文件數(shù)據(jù)數(shù)據(jù)的輸出字符流
FileWriter的使用步驟: 1. 找到目標(biāo)文件。 2. 建立數(shù)據(jù)輸出通道 3. 寫出數(shù)據(jù)。 4. 關(guān)閉資源
FileWriter要注意的事項(xiàng): 1. 使用FileWriter寫數(shù)據(jù)的時(shí)候,F(xiàn)ileWriter內(nèi)部是維護(hù)了一個(gè)1024個(gè)字符數(shù)組的,寫數(shù)據(jù)的時(shí)候會(huì)先寫入到它內(nèi)部維護(hù)的字符數(shù)組中,如果需要 把數(shù)據(jù)真正寫到硬盤上,需要調(diào)用flush或者是close方法或者是填滿了內(nèi)部的字符數(shù)組。 2. 使用FileWriter的時(shí)候,如果目標(biāo)文件不存在,那么會(huì)自動(dòng)創(chuàng)建目標(biāo)文件。 3.使用FileWriter的時(shí)候, 如果目標(biāo)文件已經(jīng)存在了,那么默認(rèn)情況會(huì)先情況文件中的數(shù)據(jù),然后再寫入數(shù)據(jù) , 如果需要在原來的基礎(chǔ)上追加數(shù)據(jù), 需要使用“new FileWriter(File , boolean)”的構(gòu)造方法,第二參數(shù)為true。
public class Demo1 { public static void main(String[] args) throws IOException { writeTest1(); } public static void writeTest1() throws IOException{ //找到目標(biāo)文件 File file = new File("F://a.txt"); //建立數(shù)據(jù)輸出通道 FileWriter fileWriter = new FileWriter(file,true); //準(zhǔn)備數(shù)據(jù),把數(shù)據(jù)寫出 String data = "今天天氣非常好!!"; fileWriter.write(data); //字符流具備解碼的功能。 //刷新字符流// fileWriter.flush(); //關(guān)閉資源 fileWriter.close(); }}//使用字符流拷貝文件public class Copy { public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new FileReader("F://Test.txt")); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E://Test.exe")); String line=null; while((line = bufferedReader.readLine())!=null){ bufferedWriter.write(line); } bufferedWriter.close(); bufferedReader.close(); }}緩沖輸入字符流
輸入字符流: ——-| Reader 所有輸入字符流的基類。 抽象類 ———-| FileReader 讀取文件字符串的輸入字符流。 ———-| BufferedReader 緩沖輸入字符流 。 緩沖 輸入字符流出現(xiàn)的目的是為了提高讀取文件 的效率和拓展了FileReader的功能。 其實(shí)該類內(nèi)部也是維護(hù)了一個(gè)字符數(shù)組
記住:緩沖流都不具備讀寫文件的能力。
BufferedReader的使用步驟: 1.找到目標(biāo)文件 2 .建立數(shù)據(jù)的輸入通道。
public static void readTest1() throws IOException{ //找到目標(biāo)文件 File file = new File("F://a.txt"); //建立數(shù)據(jù)的輸入通道。 FileReader fileReader = new FileReader(file); //建立緩沖輸入字符流 BufferedReader bufferedReader = new BufferedReader(fileReader); //讀取數(shù)據(jù) /*int content = bufferedReader.read(); //讀到了一個(gè)字符。 讀取到的字符肯定也是從Bufferedreader內(nèi)部的字符數(shù)組中獲取的到。所以效率高。 System.out.println((char)content);*/ //使用BUfferedReader拓展的功能,readLine() 一次讀取一行文本,如果讀到了文件的末尾返回null表示。 String line = null; while((line = bufferedReader.readLine())!=null){ // 雖然readLine每次讀取一行數(shù)據(jù),但是但會(huì)的line是不包含/r/n的、 System.out.println(Arrays.toString("aaa".getBytes())); } //關(guān)閉資源 bufferedReader.close(); }}緩沖輸出字符流
輸出字符流 ———-| Writer 所有輸出字符流的基類, 抽象類。 ————— | FileWriter 向文件輸出字符數(shù)據(jù)的輸出字符流。 —————-| BufferedWriter 緩沖輸出字符流 緩沖輸出字符流作用: 提高FileWriter的寫數(shù)據(jù)效率與拓展FileWriter的功能。 BufferedWriter內(nèi)部只不過是提供了一個(gè)8192長度的字符數(shù)組作為緩沖區(qū)而已,拓展了FileWriter的功能。
BufferedWriter如何使用? 1. 找到目標(biāo)文件 2. 建立數(shù)據(jù)的輸出通道
public class Demo2 { public static void main(String[] args) throws IOException { //找到目標(biāo)文件 File file = new File("F://a.txt"); //建立數(shù)據(jù)的輸出通道 FileWriter fileWriter = new FileWriter(file,true); //建立緩沖輸出流對象 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); //寫出數(shù)據(jù)// bufferedWriter.newLine(); //newLine() 換行。 實(shí)際上就是想文件輸出/r/n. bufferedWriter.write("/r/n"); bufferedWriter.write("前兩天李克強(qiáng)來蘿崗!!"); //關(guān)閉資源 bufferedWriter.flush();// bufferedWriter.close(); }}練習(xí): 緩沖輸入輸出字符流用戶登陸注冊…
public class Login { static Scanner scanner = new Scanner(System.in); public static void main(String[] args) throws IOException { while(true){ System.out.println("請選擇功能: A(注冊) B(登陸)"); String option = scanner.next(); if("a".equalsIgnoreCase(option)){ //注冊 reg(); }else if("b".equalsIgnoreCase(option)){ //登陸 login(); }else{ System.out.println("你的輸入有誤,請重新輸入..."); } } } //登陸 public static void login() throws IOException{ System.out.println("請輸入用戶名:"); String userName = scanner.next(); System.out.println("請 輸入密碼:"); String passWord = scanner.next(); String info = userName+" "+ password; //讀取文件的信息,查看是否有該用戶的信息存在,如果存在則登陸成功。 //建立數(shù)據(jù)的輸入通道 //建立緩沖輸入字符流 BufferedReader bufferedReader = new BufferedReader(new FileReader("F://users.txt")); String line = null; boolean isLogin = false; // 用于記錄是否登陸成功的標(biāo)識(shí), 默認(rèn)是登陸失敗的。 //不斷的讀取文件的內(nèi)容 while((line = bufferedReader.readLine())!=null){ if(info.equals(line)){ isLogin = true; break; } } if(isLogin){ System.out.println("歡迎"+userName+"登陸成功..."); }else{ System.out.println("不存在該用戶信息,請注冊!!"); } } //注冊 public static void reg() throws IOException{ System.out.println("請輸入用戶名:"); String userName = scanner.next(); System.out.println("請 輸入密碼:"); String password = scanner.next(); String info = userName+" "+ password; //把用戶的注冊的信息寫到文件上 File file = new File("F://users.txt"); FileWriter fileWriter = new FileWriter(file,true); //建立緩沖輸出字符流 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); //把用戶信息寫出 bufferedWriter.write(info); bufferedWriter.newLine(); //關(guān)閉資源 bufferedWriter.close(); }}
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注