1. 程式人生 > >IO【轉換流,打印流,序列化】

IO【轉換流,打印流,序列化】

ado 保存數據 字符輸入 ... 讀取文件 inpu 存在 char 字符

編碼:

把看的懂,變成看不懂的
String str = "中國";
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
解碼:

把看不懂的內容,變成能看懂的
String s = new String(bytes);
System.out.println(s);


java.io.OutputStreamWriter extends Writer
OutputStreamWriter:轉換流
作用:是字符流通向字節流的橋梁,可以指定編碼表

繼承自父類Writer的公共成員方法
寫一個字符,寫字符數組,寫字符數組的一部分,寫字符串,寫字符的一部分,刷新,關閉

構造方法:
OutputStreamWriter(OutputStream out, String charsetName) 創建使用指定字符集的 OutputStreamWriter。
參數:
OutputStream out:字節輸出流(把轉換後的字節寫入到文件中)
可以傳入FileOutputStream
String charsetName:編碼表名稱
可以傳入一個字符串格式的編碼表名稱,比如"GBK","utf-8"...,編碼表名稱不區分大小寫,如果不寫默認為系統碼表

使用步驟:
1.創建字符輸出流FileOutputStream,綁定數據的目的地
2.創建轉換流OutputStreamWriter對象,構造方法中傳入FileOutputStream和指定的編碼表名稱
3.調用OutputStreamWriter中寫數據的方法,把數據寫入到內存緩沖區中
4.釋放資源,並把數據刷新到文件中

 1 public static void main(String[] args) throws IOException {
 2         //write_GBK();
 3         write_UTF8();
 4     }
 5 
 6     /*
 7      * 使用轉換流OutputStreamWriter,寫UTF-8格式的文件
 8      */
 9     private static void write_UTF8() throws IOException {
10         //1.創建字符輸出流FileOutputStream,綁定數據的目的地
11
FileOutputStream fos = new FileOutputStream("utf-8.txt"); 12 //2.創建轉換流OutputStreamWriter對象,構造方法中傳入FileOutputStream和指定的編碼表名稱 13 OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8"); 14 //3.調用OutputStreamWriter中寫數據的方法,把數據寫入到內存緩沖區中 15 osw.write("你好"); 16 //
4.釋放資源,並把數據刷新到文件中 17 osw.close(); 18 } 19 20 /* 21 * 使用轉換流OutputStreamWriter,寫GBK格式的文件 22 */ 23 private static void write_GBK() throws IOException { 24 //1.創建字符輸出流FileOutputStream,綁定數據的目的地 25 FileOutputStream fos = new FileOutputStream("gbk.txt"); 26 //2.創建轉換流OutputStreamWriter對象,構造方法中傳入FileOutputStream和指定的編碼表名稱 27 //OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK"); 28 OutputStreamWriter osw = new OutputStreamWriter(fos); 29 //3.調用OutputStreamWriter中寫數據的方法,把數據寫入到內存緩沖區中 30 osw.write("你好"); 31 //4.釋放資源,並把數據刷新到文件中 32 osw.close(); 33 }

java.io.InputStreamReader extends Reader
* InputStreamReader流:是字節流通向字符流的橋梁,可以指定編碼表
*
* 繼承自父類Reader的公共的成員方法
* int read() 讀取單個字符。
* int read(char[] cbuf) 將字符讀入數組。
* abstract void close() 關閉該流並釋放與之關聯的所有資源。
*
* 構造方法:
* InputStreamReader(InputStream in) 創建一個使用默認字符集的 InputStreamReader。
* InputStreamReader(InputStream in, String charsetName) 創建使用指定字符集的 InputStreamReader。
* 參數:
* InputStream in:字節輸入流(把文件中保存的字節讀取出來)
* 可以傳入FileInputStream
* String charsetName:編碼表名稱
* 可以傳入一個字符串格式的編碼表名稱,比如"GBK","utf-8"...,編碼表名稱不區分大小寫,如果不寫默認為系統碼表
*
* 使用步驟:
* 1.創建字節輸入流FileInputStream對象,綁定數據源
* 2.創建轉換流InputStreamReader對象,構造方法中,傳入FileInputStream和指定的編碼表名稱
* 3.使用InputStreamReader讀取數據的方法,讀取數據
* 4.釋放資源
*
* 註意:構造方法中指定的編碼名稱,必須和要讀取的文件保持一致,否則會出現亂碼

 1 public static void main(String[] args) throws IOException {
 2         //read_GBK();
 3         read_UTF8();
 4     }
 5 
 6     /*
 7      * 使用InputStreamReader讀取UTF-8格式文件
 8      */
 9     private static void read_UTF8() throws IOException {
10         //1.創建字節輸入流FileInputStream對象,綁定數據源
11         FileInputStream fis = new FileInputStream("utf-8.txt");
12         //2.創建轉換流InputStreamReader對象,構造方法中,傳入FileInputStream和指定的編碼表名稱
13         //InputStreamReader isr = new InputStreamReader(fis,"GBK");//亂碼:浣犲ソ
14         InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//你好
15         //3.使用InputStreamReader讀取數據的方法,讀取數據
16         //int read() 讀取單個字符。 
17         int len = 0;
18         while((len = isr.read())!=-1){
19             System.out.print((char)len);
20         }
21         //4.釋放資源
22         isr.close();
23     }
24 
25     /*
26      * 使用InputStreamReader讀取GBK格式文件
27      */
28     private static void read_GBK() throws IOException {
29         //1.創建字節輸入流FileInputStream對象,綁定數據源
30         FileInputStream fis = new FileInputStream("gbk.txt");
31         //2.創建轉換流InputStreamReader對象,構造方法中,傳入FileInputStream和指定的編碼表名稱
32         //InputStreamReader isr = new InputStreamReader(fis,"GBK");
33         InputStreamReader isr = new InputStreamReader(fis);//不指定,默認使用GBK
34         //3.使用InputStreamReader讀取數據的方法,讀取數據
35         //int read() 讀取單個字符。 
36         int len = 0;
37         while((len = isr.read())!=-1){
38             System.out.print((char)len);
39         }
40         //4.釋放資源
41         isr.close();
42     }

對象的序列化和反序列化
* 對象的序列化:把對象以流的方式寫入到文件中保存
* 對象的反序列化:把文件中保存的對象,以流的方式讀取出來
對象的反序列化:把文件中保存的對象,以流的方式讀取出來
*
* 構造方法:
* ObjectInputStream(InputStream in) 創建從指定 InputStream 讀取的 ObjectInputStream。
* 參數:
* InputStream in:字節流,可以傳入FileInputStream
*
* 讀對象的方法:
* Object readObject() 從 ObjectInputStream 讀取對象。
*
* 使用步驟:
* 1.創建字節輸入流FileInputStream,綁定數據源
* 2.創建反序列化流ObjectInputStream,構造方法中傳入FileInputStream
* 3.使用ObjectInputStream中的方法readObject,讀取文件中保存的對象
* 4.釋放資源
* 5.打印對象
*
* 註意:
* 方法readObject,會拋出ClassNotFoundException(沒有class文件異常)
* 反序列化的前提,必須有對象的class文件存在
對象的序列化:把對象以流的方式寫入到文件中保存
* 構造方法:
* ObjectOutputStream(OutputStream out) 創建寫入指定 OutputStream 的 ObjectOutputStream。
* 參數:
* OutputStream out:字節流,可以傳入FileOutputStream
*
* 寫對象的方法:
* void writeObject(Object obj) 將指定的對象寫入 ObjectOutputStream。
*
* 使用步驟:
* 1.創建對象,並賦值
* 2.創建字節輸出流對象FileOutputStream,綁定數據目的地
* 3.創建序列化流ObjectOutputStream對象,構造方法中傳入FileOutputStream
* 4.使用ObjectOutputStream中的方法writeObject,把對象寫入到文件中
* 5.釋放資源
*
* 註意:
* 要序列化的類如果沒有實現Serializable接口,會拋出NotSerializableException異常
*/
類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化

Serializable接口:稱之為標記型接口
類只有實現了Serializable才能序列化和反序列化,不實現就不能
去市場賣肉,肉上有一個藍色的戳(檢測合格),買回去幹什麽有不同的吃的方式
java.lang.Cloneable:標記型接口
類實現了Cloneable就能復制,不實現就不能

序列化和反序列的是對象,如果對象中有靜態的屬性,可以序列化嗎?
靜態屬於類,不屬於對象,不能序列化
不管是靜態屬性和非靜態屬性都有默認值
age默認值是0,又是靜態屬性,不能序列化,使用默認值0
瞬態關鍵字transient:作用,阻止成員變量序列化

打印流:
* 字節打印流:PrintStream extends OutputStream
* 字符打印流:PrintWriter extends Writer
*
* 兩個打印流中的方法,完全一致:
* void print(Object obj): 輸出任意類型的數據,
* void println(Object obj): 輸出任意類型的數據,自動寫入換行操作
*
* 構造方法,就是打印流的輸出目的端
* PrintStream
* 構造方法目的地:接收File類型,接收字符串文件名,接收字節輸出流OutputStream
* PrintWriter
* 構造方法目的地:接收File類型,接收字符串文件名,接收字節輸出流OutputStream,
* 接收字符輸出流Writer
*
* 註意事項:
* 字節流寫入數據的時候,會直接把數據寫入到文件中
* 字符流寫入數據的時候,會把數據寫入到內存緩沖區中,必須刷新或者關閉,才會把數據由緩沖區刷新到文件中
*/‘‘

 1 public static void main(String[] args) throws IOException {
 2         System.out.println(97);
 3         method_04();
 4     }
 5 
 6     /*
 7      * 字符打印流的自動刷新功能
 8      * 自動刷新功能的使用必須滿足3個條件:
 9      *     1.字符打印流的輸出的目的地必須是一個流對象(字符,字節)
10      *     2.字符打印流構造方法的參數autoFlush必須是true
11      *     3.必須使用 println、printf 或 format 方法中的一個才能實現
12      * 
13      * 包含自動刷新的構造方法:
14      *     PrintWriter(OutputStream out, boolean autoFlush) 
15      *  PrintWriter(Writer out, boolean autoFlush) 
16      *  
17      * 我們可以把字符串的目的地和File類的目的地轉換為流,開啟自動刷新 
18      */
19     private static void method_04() throws IOException {
20         PrintWriter pw = new PrintWriter(new FileWriter("6.txt"),true);
21         pw.print("不能自動刷新");
22         pw.println("會自動把緩沖區中所有的內容刷新到文件中");
23     }
24 
25     /*
26      * 打印流,輸出目的地,是流對象
27      * 可以是字節輸出流,也可以是字符輸出流
28      * OutputStream Writer
29      */
30     private static void method_03() throws IOException {
31         FileOutputStream fos = new FileOutputStream("3.txt");
32         ////The constructor PrintStream(FileWriter) is undefined
33         //PrintStream ps = new PrintStream(new FileWriter("3.txt"));
34         PrintStream ps = new PrintStream(fos);
35         ps.println("字節打印流的輸出目的地是一個字節流");
36         ps.close();
37         
38         PrintWriter pw = new PrintWriter(new FileOutputStream("4.txt"));
39         pw.println("字符打印流的輸出目的地是一個字節流");
40         pw = new PrintWriter(new FileWriter("5.txt"));
41         pw.println("字符打印流的輸出目的地是一個字符流");
42         pw.close();
43     }
44 
45     /*
46      * 打印流,輸出目的,String文件名
47      */
48     private static void method_02() throws FileNotFoundException {
49         PrintWriter pw = new PrintWriter("2.txt");
50         pw.println("字符打印流,必須的刷新");
51         //pw.flush();
52         pw.close();
53     }
54 
55     /*
56      * 打印流,向File文件對象的數據目的地寫入數據
57      * 方法 print println 原樣輸出
58      * write方法 走編碼表
59      */
60     private static void method_01() throws FileNotFoundException {
61         File file = new File("1.txt");
62         PrintStream ps = new PrintStream(file);
63         //使用繼承自父類的write方法寫入數據
64         ps.write(97);
65         //使用自己特有的方法println/print寫入數據
66         ps.println(97);
67         ps.println(true);
68         ps.println("hello");
69         ps.println(8.8);
70         ps.println(‘中‘);
71         ps.close();
72     }

字符打印流的自動刷新功能
自動刷新功能的使用必須滿足3個條件:
1.字符打印流的輸出的目的地必須是一個流對象(字符,字節)
2.字符打印流構造方法的參數autoFlush必須是true
3.必須使用 println、printf 或 format 方法中的一個才能實現

包含自動刷新的構造方法:
PrintWriter(OutputStream out, boolean autoFlush)
PrintWriter(Writer out, boolean autoFlush)

我們可以把字符串的目的地和File類的目的地轉換為流,開啟自動刷新
打印流,輸出目的地,是流對象
可以是字節輸出流,也可以是字符輸出流
OutputStream Writer

java.io.Properties集合 extends Hashtable implements Map接口
*
* Properties集合的特點:
* 1.健和值默認都是String類型
* 2.集合中有自己特有的方法
* Object setProperty(String key, String value) 調用 Hashtable 的方法 put。
* String getProperty(String key) 用指定的鍵在此屬性列表中搜索屬性。 相當於Map集合中的get(key k)方法
* Set<String> stringPropertyNames() 返回此屬性列表中的鍵集. 相當於Map集合中的的keySet
* 3.和IO流相結合的方法
* 使用store方法把集合中保存的臨時數據,持久化到硬盤的文件中保存
* void store(OutputStream out, String comments)
* void store(Writer writer, String comments)
* 使用load方法把硬盤文件中保存的鍵值對,讀取出來,放入到Properties集合中
* void load(InputStream inStream)
* void load(Reader reader)

 1 public static void main(String[] args) throws IOException {
 2         method_03();
 3     }
 4 
 5     /*
 6      * 使用load方法把硬盤文件中保存的鍵值對,讀取出來,放入到Properties集合中  
 7      *     void load(InputStream inStream)
 8      *     void load(Reader reader)
 9      *     方法的參數:
10      *         InputStream inStream:不能讀取包含中文的鍵值對
11      *         Reader reader:可以讀取包含中文的鍵值對
12      * 
13      * 使用步驟:
14      *     1.創建Properties集合
15      *     2.創建字節輸入流/字符輸入對象,綁定數據源
16      *     3.使用Properties中的方法load,讀取文件中保存的鍵值對,把鍵值對保存到集合中
17      *     4.釋放資源
18      *     5.遍歷Properties集合
19      * 
20      * 註意:
21      *         prop.properties文件中使用#號可以註釋一行
22      *         prop.properties文件中key和value默認就是字符不用使用""
23      *         prop.properties文件中key和value之間可以使用=連接也可以使用空格
24      */
25     private static void method_03() throws IOException {
26         //1.創建Properties集合
27         Properties prop = new Properties();
28         //2.創建字節輸入流/字符輸入對象,綁定數據源
29         FileReader fr = new FileReader("prop.properties");
30         //3.使用Properties中的方法load,讀取文件中保存的鍵值對,把鍵值對保存到集合中
31         prop.load(fr);
32         //4.釋放資源
33         fr.close();
34         //5.遍歷Properties集合
35         for(String key : prop.stringPropertyNames()){
36             String value = prop.getProperty(key);
37             System.out.println(key+"="+value);
38         }
39     }
40 
41     /*
42      * 使用store方法把集合中保存的臨時數據,持久化到硬盤的文件中保存
43      *     void store(OutputStream out, String comments)  
44      *     void store(Writer writer, String comments)
45      *     方法的參數:
46      *         OutputStream out:不能操作中文
47      *         Writer writer:可以操作中文
48      *         String comments:註釋,保存數據的用途,可以寫"",不能寫中文,默認使用unicode編碼
49      * 使用步驟:
50      *     1.創建Properties集合,添加數據
51      *     2.創建字節輸出流或者字符輸出流對象,綁定目的地
52      *     3.使用Properties集合中的方法store把集合中的數據,寫入到文件中
53      *     4.釋放資源
54      */
55     private static void method_02() throws IOException {
56         //1.創建Properties集合,添加數據
57         Properties prop = new Properties();
58         prop.setProperty("a", "1");
59         prop.setProperty("b", "2");
60         prop.setProperty("中國", "1");
61         //2.創建字節輸出流或者字符輸出流對象,綁定目的地
62         FileWriter fw = new FileWriter("prop.properties");
63         //3.使用Properties集合中的方法store把集合中的數據,寫入到文件中
64         prop.store(fw, "");
65         //4.釋放資源
66         fw.close();
67         
68         FileOutputStream fos = new FileOutputStream("prop1.properties");
69         prop.store(fos, "save date");//寫入中文會出現亂碼
70         fos.close();
71     }
72 
73     /*
74      * 使用Properties集合中特有的方法,保存數據,遍歷集合
75      */
76     private static void method_01() {
77         Properties prop = new Properties();
78         //Object setProperty(String key, String value) 調用 Hashtable 的方法 put。 
79         prop.setProperty("a", "1");
80         prop.setProperty("b", "2");
81         prop.setProperty("c", "3");
82         
83         //Set<String> stringPropertyNames() 返回此屬性列表中的鍵集.  相當於Map集合中的的keySet 
84         Set<String> set = prop.stringPropertyNames();
85         
86         //遍歷Set集合
87         for (String key : set) {
88             //String getProperty(String key) 用指定的鍵在此屬性列表中搜索屬性。  相當於Map集合中的get(key k)方法
89             String value = prop.getProperty(key);
90             System.out.println(key+"..."+value);
91         }
92     }

使用load方法把硬盤文件中保存的鍵值對,讀取出來,放入到Properties集合中
* void load(InputStream inStream)
* void load(Reader reader)
* 方法的參數:
* InputStream inStream:不能讀取包含中文的鍵值對
* Reader reader:可以讀取包含中文的鍵值對
*
* 使用步驟:
* 1.創建Properties集合
* 2.創建字節輸入流/字符輸入對象,綁定數據源
* 3.使用Properties中的方法load,讀取文件中保存的鍵值對,把鍵值對保存到集合中
* 4.釋放資源
* 5.遍歷Properties集合
*
* 註意:
* prop.properties文件中使用#號可以註釋一行
* prop.properties文件中key和value默認就是字符不用使用""
* prop.properties文件中key和value之間可以使用=連接也可以使用空格
*/
使用store方法把集合中保存的臨時數據,持久化到硬盤的文件中保存
* void store(OutputStream out, String comments)
* void store(Writer writer, String comments)
* 方法的參數:
* OutputStream out:不能操作中文
* Writer writer:可以操作中文
* String comments:註釋,保存數據的用途,可以寫"",不能寫中文,默認使用unicode編碼
* 使用步驟:
* 1.創建Properties集合,添加數據
* 2.創建字節輸出流或者字符輸出流對象,綁定目的地
* 3.使用Properties集合中的方法store把集合中的數據,寫入到文件中
* 4.釋放資源

使用commons-IO中提供的工具類FileUtils
* static readFileToString(File file):讀取文件內容,並返回一個String;
* static writeStringToFile(File file,String content):將內容content寫入到file中;
* static copyFile(File srcFile, File destFile): 文件復制
* static copyDirectoryToDirectory(File srcDir,File destDir);文件夾復制
*
* 方法都是靜態方法,可以通過類名直接使用
* 方法的參數都是File類型

 1 public static void main(String[] args) throws IOException {
 2         //static readFileToString(File file):讀取文件內容,並返回一個String;
 3         //String s = FileUtils.readFileToString(new File("prop.properties"));
 4         String s = FileUtils.readFileToString(new File("src/cn/itcsat/demo01/Demo01FileReader.java"));
 5         System.out.println(s);
 6         
 7         //static writeStringToFile(File file,String content):將內容content寫入到file中;
 8         FileUtils.writeStringToFile(new File("fileUitls.txt"), "FileUtils工具類的時候");
 9         
10         //static copyFile(File srcFile, File destFile): 文件復制
11         FileUtils.copyFile(new File("c:\\1.jpg"), new File("d:\\1.jpg"));
12         
13         //static copyDirectoryToDirectory(File srcDir,File destDir);文件夾復制
14         FileUtils.copyDirectoryToDirectory(new File("c:\\demo"),new File("d:"));
15     }

IO【轉換流,打印流,序列化】