Java中,凡是涉及到Java程序的輸入輸出,一般都逃不過IO流,Java中的IO包括BIO和NIO,其中BIO只要是以四大基流基礎的各種各樣的阻塞流。BIO的四大基流是:InputStream OutputStream Reader Writer,但是它們都是抽象類,不能實例化對象來完成輸入輸出操作,直接使用的是它們的子類,本部分中,使用FileInputStream和FileOutputStream就可以完成輸入輸出。
BIO的四大基流
輸入流輸出流字節流字節輸入流InputStream字節輸出流OutputStream字符流字符輸入流Reader字符輸出流Writer
使用BIO流的四個步驟:
1):創建源或者目標對象(挖井).
輸入操作: 把文件中的數據流向到程序中,此時文件是源,程序是目標.
輸出操作: 把程序中的數據流向到文件中,此時文件是目標,程序是源.
2):創建IO流對象(水管).
輸入操作: 創建輸入流對象.
輸出操作: 創建輸出流對象.
3):具體的IO操作.
輸入操作: 輸入流對象的read方法.
輸出操作: 輸出流對象的write方法.
4):關閉資源(勿忘). 一旦資源關閉之後,就不能使用流對象了,否則報錯.
輸入操作: 輸入流對象.close();
輸出操作: 輸出流對象.close().
關於BIO流的方向:
讀進來,寫出去。
讀進來是指:從文件、網絡、壓縮包或其他數據源到Java程序;
寫出去是指:從Java程序到文件、網絡、壓縮包或其他輸出目標。
注意,這裡指的文件僅為純文本文件txt,不包括doc docx等文件。
package mypackage;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;//文件字節輸出流public class Test { public static void main(String[] args) throws IOException { File target = new File("stream.txt");// 程序可以自動創建txt文件 OutputStream outputStream = new FileOutputStream(target); // 四大基流不能直接實例化對象,實例化對象還要具體IO類,這裡是FileOutputStream outputStream.write("hello world!".getBytes(), 0, 12); outputStream.close(); }}
輸出1:
小結1:文件字節輸出流,將文本從程序輸出到stream.txt中。
package mypackage2;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;//文件字節輸入流public class Test { public static void main(String[] args) throws IOException { File file = new File("stream.txt"); InputStream inputStream = new FileInputStream(file); byte[] buffer = new byte[1024]; int len = -1; while ((len = inputStream.read(buffer)) != -1) { String string = new String(buffer, 0, len); // 每次讀入一個緩衝大小然後輸出 System.out.println(string); } inputStream.close(); }}
輸出2:
hello world!
小結2:文件字節輸入流,將文本從stream.txt輸入到程序中,並列印到控制臺。
package mypackage3;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class Test { // 先讀入再寫出 從myStream.txt讀入,寫出到myStream_copy.txt中 // 從myStream.txt中讀入數據,然後寫入到myStream_copy.txt中 public static void main(String[] args) throws IOException { File srcFile = new File("myStream.txt"); // 源文件 File destFile = new File("myStream_copy.txt");// 目標文件 InputStream inputStream = new FileInputStream(srcFile); OutputStream outputStream = new FileOutputStream(destFile); byte[] buffer = new byte[10]; int len = -1; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); }}
輸出3:
小結3:先讀入再寫出,從myStream.txt讀入,寫出到myStream_copy.txt中,將輸入輸出流一起使用。
package mypackage4;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class Test { // 先寫出再讀入 寫出到FileStream.txt,在讀入到程序中,列印出來 public static void main(String[] args) throws IOException { File srcFile = new File("FileStream.txt");// 程序可以自動創建txt文件 File destFile = new File("FileStream.txt"); OutputStream outputStream = new FileOutputStream(srcFile); // 四大基流不能直接實例化對象,實例化對象還要具體IO類,這裡是FileOutputStream InputStream inputStream = new FileInputStream(destFile); outputStream.write("hello world!".getBytes(), 0, 12); byte[] buffer = new byte[1024]; int len = -1; while ((len = inputStream.read(buffer)) != -1) { String string = new String(buffer, 0, len); // 每次讀入一個緩衝大小然後輸出 System.out.println(string); } outputStream.close(); inputStream.close(); }}
輸出4:
hello world!
小結4:先寫出再讀入,寫出到FileStream.txt,再讀入到程序中,列印出來,輸入輸出流一起使用。
Java中,凡是涉及到Java程序的輸入輸出,一般都逃不過IO流,Java中的IO包括BIO和NIO,其中BIO只要是以四大基流基礎的各種各樣的阻塞流。BIO的四大基流是:InputStream OutputStream Reader Writer,但是它們都是抽象類,不能實例化對象來完成輸入輸出操作,直接使用的是它們的子類,本部分中,使用FileInputStream和FileOutputStream就可以完成輸入輸出。
BIO的四大基流
使用BIO流的四個步驟:
1):創建源或者目標對象(挖井).
輸入操作: 把文件中的數據流向到程序中,此時文件是源,程序是目標.
輸出操作: 把程序中的數據流向到文件中,此時文件是目標,程序是源.
2):創建IO流對象(水管).
輸入操作: 創建輸入流對象.
輸出操作: 創建輸出流對象.
3):具體的IO操作.
輸入操作: 輸入流對象的read方法.
輸出操作: 輸出流對象的write方法.
4):關閉資源(勿忘). 一旦資源關閉之後,就不能使用流對象了,否則報錯.
輸入操作: 輸入流對象.close();
輸出操作: 輸出流對象.close().
關於BIO流的方向:
讀進來,寫出去。
讀進來是指:從文件、網絡、壓縮包或其他數據源到Java程序;
寫出去是指:從Java程序到文件、網絡、壓縮包或其他輸出目標。
問題1:為什麼有了字節流還要有字符流呢?
回答1:亂碼問題引入字符流:上面操作的文本都是英文文本,不存在任何亂碼問題,如果操作中文文本,字節流存在亂碼問題,用字符流解決。使用字節流操作漢字或特殊的符號語言的時候,容易亂碼,建議使用字符流.
問題2:為什麼有了文件字節流還要有文件字符流呢?
回答2:字符流是字節流的補充:先有字節流,後有字符流,字符流是對字節流的補充.
使用記事本打開某個文件,可以看到內容的就是文本文件,否則可以理解二進位.
一般的,操作二進位文件(圖片,音頻,視頻等)必須使用字節流.
一般的,操作文本文件使用字符流.
如果不清楚是哪一類型文件,使用字節流.
package mypackage; import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.Reader; //字符輸入流public class Test { public static void main(String[] args) throws IOException { File srcFile = new File("china.txt"); Reader reader = new FileReader(srcFile); char[] buffer = new char[1024]; int len = -1; while ((len = reader.read(buffer)) != -1) { System.out.println(buffer); } reader.close(); } }
輸出1:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結1:文件字符輸入流,將文本內容從china.txt讀入程序並列印出來。
package mypackage2; import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.Writer; //字符輸出流public class Test { public static void main(String[] args) throws IOException { File file = new File("china.txt"); Writer writer = new FileWriter(file, false); writer.write("Java程式設計師就業前景好,薪資高!"); writer.write("\n"); writer.write("一起來學習Java吧!"); writer.flush(); writer.close(); } }
輸出2:
小結2:文件字符輸出流,將程序的文本寫出到china.txt中。
package mypackage3; import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.Reader;import java.io.Writer; //先輸入後輸出 從mychina.txt文件輸入,輸出到mychina_copy.txt文件public class Test { public static void main(String[] args) throws Exception { File srcFile = new File("mychina.txt"); File destfile = new File("mychina_copy.txt"); Reader reader = new FileReader(srcFile); Writer writer = new FileWriter(destfile, false); char[] buffer = new char[1024]; int len = -1; while ((len = reader.read(buffer)) != -1) { writer.write(buffer, 0, len); } reader.close(); writer.close(); } }
輸出3:
小結3:先輸入後輸出,從mychina.txt文件輸入,輸出到mychina_copy.txt文件。
package mypackage4; import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.Reader;import java.io.Writer; //先輸出後輸入 先寫出到mychinaChar,再從mychinaChar讀入程序,列印到控制臺public class Test { public static void main(String[] args) throws Exception { File targetFile = new File("mychinaChar.txt"); Writer writer = new FileWriter(targetFile, false); Reader reader = new FileReader(targetFile); // 寫出到mychinaChar writer.write("Java程式設計師就業前景好,薪資高!"); writer.write("\n"); writer.write("一起來學習Java吧!"); writer.flush(); // 字符寫出 一定要刷新 char[] buffer = new char[1024]; int len = -1; while ((len = reader.read(buffer)) != -1) { System.out.println(buffer); } reader.close(); writer.close(); } }
輸出4:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結4:先輸出後輸入,先寫出到mychinaChar,再從mychinaChar讀入程序,列印到控制臺!
JavaIO流——文件字符流,包括文件字符輸入流FileReader,文件字符輸出流FileWriter,這兩種流聯合起來完成最基本的字符操作。
比較四種方式下,對於同一文件stream.txt,JavaIO流輸入輸出操作的總時間。分別是:不使用緩衝流不使用byte數組(代碼1),使用緩衝流(代碼2),使用byte數組(代碼3),同時使用緩衝流和byte數組(代碼4)。
注意:txt內容一定要足夠大,否則效果不明顯,IO流一下子就操作完了
package mypackage; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.io.Writer; //用緩衝流和緩衝數組提高讀寫效率 要將文本內容弄長一些效果才明顯 同時擁有讀入流和寫出流//先讀入後寫出 從stream.txt中讀入,寫出到stream_copy.txt中public class Test { public static void main(String[] args) throws Exception { long begin = System.currentTimeMillis(); File srcFile = new File("stream.txt"); File destFile = new File("stream_copy.txt"); InputStream inputStream = new FileInputStream(srcFile); OutputStream outputStream = new FileOutputStream(destFile); int len = -1; while ((len = inputStream.read()) != -1) { outputStream.write(len); } inputStream.close(); outputStream.close(); System.out.println(System.currentTimeMillis() - begin); } }
輸出1:
640
小結1:不使用緩衝流不使用byte數組,IO流操作速度最慢,640毫秒。
package mypackage2緩衝流; import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.io.Writer; //用緩衝流和緩衝數組提高讀寫效率 要將文本內容弄長一些效果才明顯 同時擁有讀入流和寫出流//先讀入後寫出 從stream.txt中讀入,寫出到stream_copy.txt中public class Test { public static void main(String[] args) throws Exception { long begin = System.currentTimeMillis(); File srcFile = new File("stream.txt"); File destFile = new File("stream_copy.txt"); InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile)); OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(destFile)); int len = -1; while ((len = inputStream.read()) != -1) { outputStream.write(len); } inputStream.close(); outputStream.close(); System.out.println(System.currentTimeMillis() - begin); } }
輸出2:
8
小結2:使用緩衝流,加快了速度。
package mypackage3_1024數組; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.io.Writer; //用緩衝流和緩衝數組提高讀寫效率 要將文本內容弄長一些效果才明顯 同時擁有讀入流和寫出流//先讀入後寫出 從stream.txt中讀入,寫出到stream_copy.txt中public class Test { public static void main(String[] args) throws Exception { long begin = System.currentTimeMillis(); File srcFile = new File("stream.txt"); File destFile = new File("stream_copy.txt"); InputStream inputStream = new FileInputStream(srcFile); OutputStream outputStream = new FileOutputStream(destFile); byte[] buffer = new byte[1024]; // 每次1024個 int len = -1; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); System.out.println(System.currentTimeMillis() - begin); } }
輸出3:
1
小結3:使用了byte數組,加快了速度。
package mypackage4緩衝流_1024數組; import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.io.Writer; //用緩衝流和緩衝數組提高讀寫效率 要將文本內容弄長一些效果才明顯 同時擁有讀入流和寫出流//先讀入後寫出 從stream.txt中讀入,寫出到stream_copy.txt中public class Test { public static void main(String[] args) throws Exception { long begin = System.currentTimeMillis(); File srcFile = new File("stream.txt"); File destFile = new File("stream_copy.txt"); InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile)); OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(destFile)); byte[] buffer = new byte[1024]; // 每次1024個 int len = -1; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); System.out.println(System.currentTimeMillis() - begin); } }
輸出4:
1
小結4:同時使用緩衝流和byte數組,大大加快速度。
緩衝流和byte數組(字節流byte數組,字符流char數組)都可以加速IO流讀寫速度,本程序(代碼1、代碼2、代碼3、代碼4)中由於stream.txt文本不夠大,所以效果不是很明顯。實際上,第四種方式,同時使用緩衝流和byte數組,速度是最快的,讀者知道就好。
(1)不使用緩衝流不使用byte數組:直接使用文件字節輸入和文件字節輸出;
(2)使用緩衝流包一層:緩衝流包裹文件字節輸入和文件字節輸出;
(3)使用byte數組:文件字節讀取和文件字節寫出都是用byte數組;
(4)同時使用緩衝流和byte數組:緩衝流包一層,然後得到的緩衝流的讀入和寫出都用byte數組.
編碼: 把字符串轉換為byte數組.
解碼: 把byte數組轉換為字符串.
一定要保證編碼和解碼的字符相同,否則亂碼.
代碼1:
package mypackage; import java.util.Arrays; //編碼: 把字符串轉換為byte數組.//解碼: 把byte數組轉換為字符串.//一定要保證編碼和解碼的字符相同,否則亂碼.public class Test { public static void main(String[] args) throws Exception { String mString = "Java程式設計師就業前景好,薪資高"; // 字符串 byte[] data = mString.getBytes("UTF-8"); // 字符串變為byte數組,編碼 // String ret=new String(data,"GBK"); //使用GBK解碼亂碼,一定要保證編碼和解碼的字符相同,否則亂碼. // System.out.println(ret); String ret = new String(data, "UTF-8"); // byte數組變為字符串,解碼 System.out.println(ret); // 列印解碼 } }
輸出1:
Java程式設計師就業前景好,薪資高
小結1:一定要保證編碼和解碼的字符相同,否則亂碼.
代碼2——困境:
package mypackage1; //編碼: 把字符串轉換為byte數組.//解碼: 把byte數組轉換為字符串.//一定要保證編碼和解碼的字符相同,否則亂碼.public class Test { public static void main(String[] args) throws Exception { String mString = "Java程式設計師就業前景好,薪資高"; byte[] data = mString.getBytes("UTF-8"); // 編碼UTF-8 String ret = new String(data, "GBK"); // 解碼GBK } }
小結2:這裡編碼UTF-8,但是解碼GBK,接下來怎麼破,且看代碼3.
代碼3——破解代碼2的困境:
package mypackage1; //編碼: 把字符串轉換為byte數組.//解碼: 把byte數組轉換為字符串.//一定要保證編碼和解碼的字符相同,否則亂碼.public class Test { public static void main(String[] args) throws Exception { String mString = "Java程式設計師就業前景好,薪資高"; byte[] data = mString.getBytes("UTF-8"); // 編碼UTF-8 String ret = new String(data, "GBK"); // 解碼GBK data = ret.getBytes("GBK"); // 編碼 ret = new String(data, "UTF-8"); System.out.println(ret); } }
輸出3:
Java程式設計師就業前景好,薪資高
小結3:所謂的編碼解碼,無非就是正過來一次,反過來一次罷了,這裡編碼UTF-8,解碼GBK,接下來只能編碼GBK,解碼UTF-8破解,就是破解方法和前面的編碼解碼反過來就好了。
字符編碼:只要記住兩條,
第一,編碼和解碼的字符要相同,否則亂碼;
第二,不管前面編碼解碼多麼複雜,只要反過來操作就可以還原內容,列印出來。
2.1 字符串編碼為byte數組,byte數組解碼為字符串;
2.2 困境:字符串UTF-8編碼為byte數組,byte數組GBK解碼為字符串;
2.3 解決:字符串UTF-8編碼為byte數組,byte數組GBK解碼為字符串,然後,字符串再次GBK編碼一次得到byte數組,最後byte數組UTF-8解碼一次得到字符串,列印出來。
JavaIO流——轉換流,將字節流轉換為字符流。
InputStreamReader:把字節輸入流轉成字符輸入流.
OutputStreamWriter:把字節輸出流轉成字符輸出流.
為什麼有字節轉字符流,沒有字符轉字節流?
字節流可以操作一切文件(純文本文件/二進位文件).字符流是用來操作中文純文本使用的,本身是對字節流的增強.所以字節流轉換為字符流是安全的,字符流轉換為字節流不一定安全,所以沒有字符流轉換
為字節流,個人理解,非官方解釋,皮!
解釋上圖:
字符流是接口,轉化流是字符流的非抽象子類,可以實例化對象,但是使用字節流對象作為構造器參數,然後文件字符流和是轉換流的子類,可以單獨使用
先讀入originStream.txt內容到程序,再將內容寫出到targetStream.txt:
package mypackage_輸入流輸出流; //轉換流:把字節流轉成字符流: //InputStreamReader:把字節輸入流轉成字符輸入流.//OutputStreamWriter:把字節輸出流轉成字符輸出流.//為什麼有字節轉字符流,沒有字符轉字節流.// 字節流可以操作一切文件(純文本文件/二進位文件).// 字符流是用來操作中文純文本使用的,本身是對字節流的增強. import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.Reader;import java.io.Writer; //先讀入originStream.txt內容到程序,再將內容寫出到targetStream.txtpublic class Test { public static void main(String[] args) throws Exception { File originStream = new File("originStream.txt"); File targetStream = new File("targetStream.txt"); Reader reader = new InputStreamReader(new FileInputStream(originStream)); Writer writer = new OutputStreamWriter(new FileOutputStream(targetStream)); char[] buffer = new char[1024]; // 字節流用byte[1024]作為緩衝,字符流用char[1024]作為緩衝 // 注意,這個緩衝buffer數組大小是任意的,可以是5,可以是10,可以是1000,可以是1024 僅表示一次讀寫的字節數或字符數 int len = -1; while ((len = reader.read(buffer)) != -1) { writer.write(buffer, 0, len); } reader.close(); writer.close(); } }
輸入:
輸出1:
小結1:上面的邏輯上沒有特別之處,就是輸入流+輸出流,先讀入originStream.txt內容到程序,再將內容寫出到targetStream.txt。演示的意義在於加入了轉換流,將字符操作變為字節操作,用於完成輸入輸出。
Java BIO中的轉換流,將字節流轉換為字符流,為我們提供了一種字符操作變為字節操作,進而實現輸入輸出的方式。
代碼演示的邏輯上沒有特別之處,就是輸入流+輸出流,先讀入originStream.txt內容到程序,再將內容寫出到targetStream.txt。演示的意義在於加入了轉換流,將字符操作變為字節操作,用於完成輸入輸出。
JavaIO流——內存流,內存流實際是數組流/字符串流
內存流(數組流):適配器模式:
1):字節內存流: ByteArrayInputStream/ByteArrayOutputStream 先將數據先臨時存在byte數組中,待會再從byte數組中獲取出來.
2):字符內存流: CharArrayReader/CharArrayWriter 先將數據先臨時存在char數組中,待會再從char數組中獲取出來.
3):字符串流:StringReader/StringWriter 先將數據(字符串)從程序寫出到stringwriter中,即臨時存儲到字符串中,然後將stringwriter中的內容讀入程序並列印出來。
package mypackage_字節數組流; import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream; //內存流(數組流):適配器模式:// 把數據先臨時存在數組中,待會再從數組中獲取出來.// 1):字節內存流: ByteArrayInputStream/ByteArrayOutputStream 數據臨時存放到數組中// 2):字符內存流: CharArrayReader/CharArrayWriter 數據臨時存放到數組中// 3):字符串流:StringReader/StringWriter(把數據臨時存儲到字符串中)//字節內存流——字節數組流 內存流實際是數組流,字節內存流和字符內存流都是將數據存放到數組中,字符串流將數據存放到字符串中。public class Test { public static void main(String[] args) throws Exception { // 數據從程序寫出到內存(即數組) 內存字節輸出流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write("Java is the best language".getBytes()); byte[] buffer = byteArrayOutputStream.toByteArray(); byteArrayOutputStream.close(); // 數據從內存(即數組)讀入到程序 內存字節輸入流 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); byte[] _bytes = new byte[1024];// 字節緩衝為byte數組 int len = -1; while ((len = byteArrayInputStream.read(_bytes)) != -1) { System.out.println(new String(_bytes, 0, len)); } byteArrayInputStream.close(); }}
輸出1:
Java is the best language
小結1:這裡演示字節內存流,先將「Java is the best language」從程序寫出到內存數組buffer中,然後將buffer數組中的內容讀入程序並列印出來。
package mypackage_字符數組流; import java.io.CharArrayReader;import java.io.CharArrayWriter; public class Test { public static void main(String[] args) throws Exception { // 數據從程序寫出到內存(即數組) CharArrayWriter charArrayWriter = new CharArrayWriter(); charArrayWriter.write("Java程式設計師就業前景好,薪資高!一起來學習Java吧!"); char[] buffer = charArrayWriter.toCharArray(); charArrayWriter.close(); // 數據從內存(即數組)讀入到程序 CharArrayReader charArrayReader = new CharArrayReader(buffer); char[] _chars = new char[1024];// 字節緩衝為byte數組 int len = -1; while ((len = charArrayReader.read(_chars)) != -1) { System.out.println(new String(_chars, 0, len)); } charArrayReader.close(); } }
輸出2:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結2:這裡演示字符內存流,先將「Java程式設計師就業前景好,薪資高!一起來學習Java吧!」從程序寫出到內存數組buffer中,然後將buffer數組中的內容讀入程序並列印出來。不同的是,字節內存流用byte數組,字符內存流用char數組。
package 字符串流; import java.io.StringReader;import java.io.StringWriter; public class Test { public static void main(String[] args) throws Exception { // 數據從程序寫出到內存(即數組) StringWriter stringWriter = new StringWriter(); stringWriter.write("Java程式設計師就業前景好,薪資高!一起來學習Java吧!"); // 數據從內存(即數組)讀入到程序 StringReader stringReader = new StringReader(stringWriter.toString()); char[] _chars = new char[1024];// 字節緩衝為byte數組 int len = -1; while ((len = stringReader.read(_chars)) != -1) { System.out.println(new String(_chars, 0, len)); } stringReader.close(); stringWriter.close(); }}
輸出3:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結3:這裡演示字符串流,先將「Java程式設計師就業前景好,薪資高!一起來學習Java吧!」從程序寫出到stringwriter中,然後將stringwriter中的內容讀入程序並列印出來。
Java內存流分為三種字節內存流、字符內存流、字符串流,都分別有輸入流和輸出流,
1):字節內存流: ByteArrayInputStream/ByteArrayOutputStream 先將數據先臨時存在byte數組中,待會再從byte數組中獲取出來.
2):字符內存流: CharArrayReader/CharArrayWriter 先將數據先臨時存在char數組中,待會再從char數組中獲取出來.
3):字符串流:StringReader/StringWriter 先將數據(字符串)從程序寫出到stringwriter中,即臨時存儲到字符串中,然後將stringwriter中的內容讀入程序並列印出來。
Java中,凡是涉及到Java程序的輸入輸出,一般都逃不過IO流,Java中的IO包括BIO和NIO,其中BIO只要是以四大基流基礎的各種各樣的阻塞流。BIO的四大基流是:InputStream OutputStream Reader Writer,但是它們都是抽象類,不能實例化對象來完成輸入輸出操作,直接使用的是它們的子類,本部分中,使用FileInputStream和FileOutputStream就可以完成輸入輸出。
BIO的四大基流
使用BIO流的四個步驟:
1):創建源或者目標對象(挖井).
輸入操作: 把文件中的數據流向到程序中,此時文件是源,程序是目標.
輸出操作: 把程序中的數據流向到文件中,此時文件是目標,程序是源.
2):創建IO流對象(水管).
輸入操作: 創建輸入流對象.
輸出操作: 創建輸出流對象.
3):具體的IO操作.
輸入操作: 輸入流對象的read方法.
輸出操作: 輸出流對象的write方法.
4):關閉資源(勿忘). 一旦資源關閉之後,就不能使用流對象了,否則報錯.
輸入操作: 輸入流對象.close();
輸出操作: 輸出流對象.close().
關於BIO流的方向:
讀進來,寫出去。
讀進來是指:從文件、網絡、壓縮包或其他數據源到Java程序;
寫出去是指:從Java程序到文件、網絡、壓縮包或其他輸出目標。
JavaIO流——文件字符流,包括文件字符輸入流FileReader,文件字符輸出流FileWriter,這兩種流聯合起來完成最基本的字符操作。
緩衝流和byte數組(字節流byte數組,字符流char數組)都可以加速IO流讀寫速度,本程序(代碼1、代碼2、代碼3、代碼4)中由於stream.txt文本不夠大,所以效果不是很明顯。實際上,第四種方式,同時使用緩衝流和byte數組,速度是最快的,讀者知道就好。
(1)不使用緩衝流不使用byte數組:直接使用文件字節輸入和文件字節輸出;
(2)使用緩衝流包一層:緩衝流包裹文件字節輸入和文件字節輸出;
(3)使用byte數組:文件字節讀取和文件字節寫出都是用byte數組;
(4)同時使用緩衝流和byte數組:緩衝流包一層,然後得到的緩衝流的讀入和寫出都用byte數組.
字符編碼:只要記住兩條,
第一,編碼和解碼的字符要相同,否則亂碼;
第二,不管前面編碼解碼多麼複雜,只要反過來操作就可以還原內容,列印出來。
2.1 字符串編碼為byte數組,byte數組解碼為字符串;
2.2 困境:字符串UTF-8編碼為byte數組,byte數組GBK解碼為字符串;
2.3 解決:字符串UTF-8編碼為byte數組,byte數組GBK解碼為字符串,然後,字符串再次GBK編碼一次得到byte數組,最後byte數組UTF-8解碼一次得到字符串,列印出來。
JavaIO流——轉換流,將字節流轉換為字符流。
InputStreamReader:把字節輸入流轉成字符輸入流.
OutputStreamWriter:把字節輸出流轉成字符輸出流.
為什麼有字節轉字符流,沒有字符轉字節流?
字節流可以操作一切文件(純文本文件/二進位文件).字符流是用來操作中文純文本使用的,本身是對字節流的增強.所以字節流轉換為字符流是安全的,字符流轉換為字節流不一定安全,所以沒有字符流轉換為字節流,個人理解,非官方解釋,皮!
字符流是接口,轉化流是字符流的非抽象子類,可以實例化對象,但是使用字節流對象作為構造器參數,然後文件字符流和是轉換流的子類,可以單獨使用
Java BIO中的轉換流,將字節流轉換為字符流,為我們提供了一種字符操作變為字節操作,進而實現輸入輸出的方式。
代碼演示的邏輯上沒有特別之處,就是輸入流+輸出流,先讀入originStream.txt內容到程序,再將內容寫出到targetStream.txt。演示的意義在於加入了轉換流,將字符操作變為字節操作,用於完成輸入輸出。
Java內存流就是讓數據在內存中呆一會,分為三種字節內存流、字符內存流、字符串流,都分別有輸入流和輸出流,
1):字節內存流: ByteArrayInputStream/ByteArrayOutputStream 先將數據先臨時存在byte數組中,待會再從byte數組中獲取出來.
2):字符內存流: CharArrayReader/CharArrayWriter 先將數據先臨時存在char數組中,待會再從char數組中獲取出來.
3):字符串流:StringReader/StringWriter 先將數據(字符串)從程序寫出到stringwriter中,即臨時存儲到字符串中,然後將stringwriter中的內容讀入程序並列印出來。
IO,對象傳輸的基石(一),完成了。
天天打碼,天天進步!!!
如果覺得本文有用,可以關注+轉發,您的鼓勵就是我創作的最大動力。