IO流(字節流主要用於讀寫二進制文件;字符流主要用於讀寫文本性文件)


1.  File類

File類在java中表示(帶路徑的)文件或者目錄

1).File常用屬性和方法

 1 public static void main(String[] args) {
 2 
 3         
 4 
 5          // 給定路徑創建File對象
 6 
 7          // File file = new File("D:"+File.separator+"javatest"+File.separator+"a.txt");
 8 
 9          File file = new File("d:\\javatest\\b.mp3");
10 
11          System.out.println(file);
12 
13         
14 
15          // 文件基本屬性
16 
17          System.out.println(file.canExecute());
18 
19          System.out.println(file.canRead());
20 
21          System.out.println(file.canWrite());
22 
23         
24 
25          // 文件的創建、刪除
26 
27          if(!file.exists()) {
28 
29              
30 
31               booleanr;
32 
33               try {
34 
35                    r = file.createNewFile();
36 
37                    if(r) {
38 
39                        System.out.println("文件創建成功");
40 
41                    }
42 
43               } catch (IOExceptione) {
44 
45                    e.printStackTrace();
46 
47               }
48 
49          }
50 
51         
52 
53          // 刪除文件
54 
55          file.delete();
56 
57      }

創建文件時會拋出檢查時異常IOException

2).File的路徑相關

 

 1 public static void main(String[] args) {
 2 
 3         
 4 
 5           File file = new File("d:\\javatest\\a");
 6 
 7 //       File file = new File("a.txt");
 8 
 9         
10 
11          // 獲取file的絕對路徑
12 
13          System.out.println(file.getAbsolutePath());
14 
15          // 獲取file的創建時的路徑字符串
16 
17          System.out.println(file.getPath());
18 
19          // 獲取文件或者目錄的名字
20 
21          System.out.println(file.getName());
22 
23          // 獲取文件或者目錄的父目錄
24 
25          System.out.println(file.getParent());
26 
27         
28 
29      }

 

注意:如果file是相對路徑,相對路徑的當前路徑是工程目錄(java17)

3). 目錄的創建

 1 public static void main(String[] args) {
 2 
 3        
 4 
 5          File file = new File("d:\\javatest\\c\\d\\e");
 6 
 7        
 8 
 9         if(!file.exists()) {
10 
11             booleanr;
12 
13            
14 
15             try {
16 
17                 // 一次只能創建一個目錄
18 
19                 // r = file.mkdir();
20 
21                 r = file.mkdirs();
22 
23                 if(r) {
24 
25                     System.out.println("目錄創建成功");
26 
27                 }
28 
29             } catch (Exception e) {
30 
31                 e.printStackTrace();
32 
33             }
34 
35            
36 
37          }
38 
39     }

4).目錄的遍歷

list():返回一個file表示的目錄中的子目錄或者文件,字符串數組類型

listFiles():返回一個file表示的目錄中的子目錄或者文件,File數組類型

 1 public static void main(String[] args) {
 2 
 3         
 4 
 5          // 需求:遍歷d:\javatest目錄
 6 
 7          // list()
 8 
 9          Filefile=  newFile("d:\\javatest");
10 
11         
12 
13         
14 
15          /*
16 
17          String[] list = file.list();
18 
19         
20 
21          for (String str : list) {
22 
23               System.out.print(str);
24 
25               File f = new File(file.getPath()+"\\"+str);
26 
27               if(f.isDirectory()) {
28 
29                    System.out.println(" 目錄");
30 
31               }else {
32 
33                    System.out.println(" 文件");
34 
35               }
36 
37          }*/
38 
39         
40 
41         
42 
43          // listFiles();
44 
45          File[] listFiles = file.listFiles();
46 
47          for (Filef :listFiles) {
48 
49               System.out.print(f.getName());
50 
51               if(f.isDirectory()) {
52 
53                    System.out.println(" 目錄");
54 
55               }else {
56 
57                    System.out.println(" 文件");
58 
59               }
60 
61          }
62 
63      }

2. IO流

1).  流

流(stream):流是一連串流動的數據(字節、字符),以先進先出的方式發送的信息的通道中。

2).  輸入流和輸出流

輸入流

數據從源數據源流入程序的過程稱為輸入流。可以理解為從源數據源讀取數據到程序的過程

 

 

 

輸出流

數據從程序流出到目的地的過程稱為輸出流。可以理解為把數據從程序寫入目的地的過程

 

 

 

注:數據源一般指提供數據的原始媒介,一般常見有文件、數據庫、雲端、其他硬件等能提供數據的媒介。

 

3).  流的分類

按照流向分為輸入流和輸出流

按照處理單元分為字節流和字符流

按照功能分為節點流和轉換流。

 

 

 

3 .  InputStream/OutputStream

InputStream  是所有字節輸入流的抽象父類,提供了

read   讀取一個字節

read(byte[] buf) 讀取一定量的字節到緩沖區數組buf中。

 

OutputStream  是所有字節輸出流的抽象父類,提供了

write() 寫入一個字節

write(byte[] buf) 寫入一定量的字節到輸出流

 

FileInputStream文件字節輸入流,專門用於從文件中讀取字節到程序內存中。

FileOutputStream文件字節輸出流,專門用於從內存中寫入字節到文件中。

 

需求:從文件讀取一個字節

 1 public static void main(String[] args) {
 2 
 3         
 4 
 5          // 需求:讀取一個文件中的一個字節
 6 
 7          File file = new File("d:\\javatest\\a.txt");
 8 
 9         
10 
11          // 【1】創建管道
12 
13          FileInputStreamin = null;
14 
15         
16 
17          try {
18 
19               in = newFileInputStream(file);
20 
21              
22 
23               // 【2】從管道讀取一個字節
24 
25               /*
26 
27               int t;
28 
29               t = in.read();
30 
31               t = in.read();
32 
33               t = in.read();
34 
35               t = in.read();
36 
37               */
38 
39               // System.out.println(t);
40 
41              
42 
43               // 循環讀取一個字節
44 
45               intt;
46 
47               StringBuildersb = newStringBuilder();
48 
49               while( (t=in.read()) != -1 ) {
50 
51                    sb.append((char)t);
52 
53               }
54 
55              
56 
57               System.out.println(sb.toString());
58 
59              
60 
61              
62 
63              
64 
65          } catch (FileNotFoundExceptione) {
66 
67               e.printStackTrace();
68 
69          } catch(IOExceptione) {
70 
71               e.printStackTrace();
72 
73          }
74 
75         
76 
77          // 【3】關閉流管道
78 
79          try {
80 
81               in.close();
82 
83          } catch (IOExceptione) {
84 
85               e.printStackTrace();
86 
87          }
88 
89      }

一次讀取多個字節

  1 public static void main(String[] args) {
  2 
  3         
  4 
  5          // 需求:一次讀取多個字節
  6 
  7          File file = new File("d:\\javatest\\a.txt");
  8 
  9         
 10 
 11          // 【1】創建管道
 12 
 13           FileInputStreamin = null;
 14 
 15         
 16 
 17          try {
 18 
 19               in = newFileInputStream(file);
 20 
 21              
 22 
 23               // 【2】從管道讀取多個字節到緩沖區
 24 
 25               /*
 26 
 27               byte[] buf = new byte[5];
 28 
 29               intlen;
 30 
 31               len = in.read(buf);
 32 
 33               len = in.read(buf);
 34 
 35               len = in.read(buf);
 36 
 37               len = in.read(buf);
 38 
 39              
 40 
 41               for(byte b:buf) {
 42 
 43                    System.out.print((char)b+"\t");
 44 
 45               }
 46 
 47               System.out.println(len);
 48 
 49               */
 50 
 51              
 52 
 53               // 通過循環讀取文件
 54 
 55               byte[] buf = newbyte[5];
 56 
 57               intlen;
 58 
 59               StringBuildersb = newStringBuilder();
 60 
 61               while( (len=in.read(buf)) != -1 ) {
 62 
 63                    // 讀取的內容是原始二進制流,需要根據編碼的字符集解碼成對於字符
 64 
 65                    String str = new String(buf,0,len);
 66 
 67                    sb.append(str);
 68 
 69               }
 70 
 71               System.out.println(sb.toString());
 72 
 73              
 74 
 75              
 76 
 77              
 78 
 79              
 80 
 81          } catch (FileNotFoundExceptione) {
 82 
 83               e.printStackTrace();
 84 
 85          } catch(IOExceptione) {
 86 
 87               e.printStackTrace();
 88 
 89          }
 90 
 91         
 92 
 93          // 【3】關閉流管道
 94 
 95          try {
 96 
 97               in.close();
 98 
 99          } catch (IOExceptione) {
100 
101               e.printStackTrace();
102 
103          }
104 
105      }

需求:按照指定編碼寫入文件

 1 public static void main(String[] args) {
 2 
 3         
 4 
 5         
 6 
 7          File file = new File("d:\\javatest\\c.txt");
 8 
 9         
10 
11          FileOutputStreamout = null;
12 
13         
14 
15          try {
16 
17               // 【1】創建輸出流管道
18 
19               out = newFileOutputStream(file);
20 
21              
22 
23               // 【2】寫入數據到管道中
24 
25               // 一次寫入一個字節
26 
27               /*
28 
29               out.write(97);
30 
31               out.write(98);
32 
33               out.write(99);
34 
35               */
36 
37              
38 
39               // 一次寫入多個字節
40 
41               String str = "hello world";
42 
43               // gbk
44 
45               /*
46 
47               byte[] buf = str.getBytes();
48 
49               out.write(buf);
50 
51               */
52 
53              
54 
55               byte[] buf = str.getBytes("UTF-8");
56 
57               out.write(buf);
58 
59              
60 
61               System.out.println("寫入完成!");
62 
63              
64 
65          } catch (FileNotFoundExceptione) {
66 
67               e.printStackTrace();
68 
69          } catch (IOExceptione) {
70 
71               e.printStackTrace();
72 
73          }
74 
75         
76 
77          // 【3】關閉流
78 
79          try {
80 
81               out.close();
82 
83          } catch (IOExceptione) {
84 
85               e.printStackTrace();
86 
87          }
88 
89      }

注意:

[1]字符串寫入文件時一定會存在編碼問題

[2]使用utf8編碼寫入文件時,如果不含中文時,win系統會對文件的編碼造成誤判。

[3]通過字節流寫入文件時,向管道寫入一個字節,該字節立即寫入文件中。

 

總結

InputStream/OutputStream用於字節的讀寫。主要用於讀取二進制文件(圖片、音頻、視頻),也可以讀取文件性文件。

 

需求:請把d:\\javatest\\logo.png 復制到工程目錄中,並顯示復制進度。

public static void main(String[] args) throwsFileNotFoundException,IOException {

        File oriFile = new File("d:\\javatest\\logo.jpg");

        File toFile = new File("logo.jpg");

 
        longtotalLen = oriFile.length();    // 文件大小

        longcpyedLen = 0;   // 已復制完成的大小

        floatprogress = 0.0f;

       

        FileInputStreamin = newFileInputStream(oriFile);

        FileOutputStreamout = newFileOutputStream(toFile);

       
        // 一次讀取1kb

        byte[] buf = newbyte[512];

        intlen;

        while( (len=in.read(buf)) != -1) {

            out.write(buf, 0, len);

            cpyedLen += len;

            progress = cpyedLen*1.0f/totalLen;

            System.out.println(progress);
         

        }

       

        in.close();

        out.close();

       

        System.out.println("復制完成!");

       

    }

4.Reader/Writer

Reader 是字符輸入流的抽象父類,提供了

read一次讀取一個字符

read(char[] cbuf)一次讀取多個字符到字符緩沖區cbuf,返回長度表示讀取的字符個數。

 

Writer是字符輸出流的抽象父類,提供了

write

write(char[] cbuf)

write(string)

 

FileReader文件字符輸入流,專門用於讀取默認字符編碼文本性文件。

 

FileWriter文件字符輸出流,專門用於寫入默認字符編碼的文本性文件。為了提高效率,FileWriter內部存在一個字節緩沖區,用於對待寫入的字符進行統一編碼到字節緩沖區,一定要在關閉流之前,調用flush方法刷新緩沖區。

 

需求:一次讀取一個字符/多個字符到cbuf

 1 public static void main(String[] args) throwsIOException {
 2 
 3        
 4 
 5         File file = new File("d:\\javatest\\d.txt");
 6 
 7        
 8 
 9         FileReaderreader = newFileReader(file);
10 
11        
12 
13         // 【1】一次讀取一個字符
14 
15         /*
16 
17         int c;
18 
19         c = reader.read();
20 
21         c = reader.read();
22 
23         c = reader.read();
24 
25         c = reader.read();
26 
27         c = reader.read();
28 
29         System.out.println((char)c);
30 
31         */
32 
33        
34 
35         // 【2】一次讀取多個字符到cbuf中
36 
37         /*
38 
39         char[] cbuf = new char[2];
40 
41         intlen;
42 
43         len = reader.read(cbuf);
44 
45         len = reader.read(cbuf);
46 
47         len = reader.read(cbuf);
48 
49         len = reader.read(cbuf);
50 
51         System.out.println(Arrays.toString(cbuf));
52 
53         System.out.println(len);
54 
55         */
56 
57        
58 
59         char[] cbuf = newchar[2];
60 
61         intlen;
62 
63         StringBuildersb = newStringBuilder();
64 
65         while( (len=reader.read(cbuf)) != -1 ) {
66 
67             sb.append(cbuf,0,len);
68 
69         }
70 
71        
72 
73         System.out.println(sb);
74 
75     }

需求:寫入字符到文件中

 1 public static void main(String[] args) throwsIOException {
 2 
 3         
 4 
 5         
 6 
 7          File file = new File("d:\\javatest\\f.txt");
 8 
 9         
10 
11          FileWriterwriter = newFileWriter(file);
12 
13         
14 
15          // 【1】一次寫入一個字符
16 
17          /*writer.write('中');
18 
19          writer.write('國');*/
20 
21         
22 
23          // 【2】一次寫入多個字符
24 
25          /*char[] cbuf = {'h','e','l','l','o','中','國'};
26 
27          writer.write(cbuf);*/
28 
29         
30 
31          // 【3】一次寫入一個字符串
32 
33          String str = "hello你好";
34 
35          writer.write(str);
36 
37         
38 
39         
40 
41          // 刷新字節緩沖區
42 
43          writer.flush();
44 
45         
46 
47          // 關閉流通道
48 
49          writer.close();
50 
51         
52 
53          System.out.println("寫入完成");
54 
55      }

5. 轉換流

InputStreamReader繼承於Reader,是字節流通向字符流的橋梁,可以把字節流按照指定編碼解碼成字符流。

 

OutputStreamWriter繼承於Writer,是字符流通向字節流的橋梁,可以把字符流按照指定的編碼編碼成字節流。

1.5.1            轉換流工作原理

 

 

 

需求:寫入utf8文件

 1 /**
 2 
 3  * 把一個字符串以utf8編碼寫入文件
 4 
 5  */
 6 
 7 publicclass Test01 {
 8 
 9      public static void main(String[] args) throwsIOException {
10 
11         
12 
13         
14 
15          String str = "hello中國";
16 
17          File file = new File("d:\\javatest\\g.txt");
18 
19         
20 
21          // 【1】創建管道
22 
23          FileOutputStreamout = newFileOutputStream(file);
24 
25          OutputStreamWriterwriter = newOutputStreamWriter(out, "utf8");
26 
27         
28 
29          // 【2】寫入管道
30 
31          writer.write(str);
32 
33         
34 
35          // 【3】刷新緩沖區
36 
37          writer.flush();
38 
39         
40 
41          // 【4】關閉管道
42 
43          out.close();
44 
45          writer.close();
46 
47         
48 
49          System.out.println("寫入完成");
50 
51      }
52 
53 }

 

需求:讀取utf8文件

 1 /**
 2 
 3  * 讀取utf8編碼的文本文件
 4 
 5  */
 6 
 7 public class Test01 {
 8 
 9      public static void main(String[] args) throwsIOException {
10 
11         
12 
13          File file = new File("d:\\javatest\\g.txt");
14 
15         
16 
17          // 【1】建立管道
18 
19          FileInputStreamin = newFileInputStream(file);
20 
21          InputStreamReaderreader = newInputStreamReader(in, "UTF-8");
22 
23         
24 
25          char[] cbuf = newchar[2];
26 
27          intlen;
28 
29         
30 
31          StringBuildersb = newStringBuilder();
32 
33          while( (len=reader.read(cbuf))!=-1 ) {
34 
35               sb.append(cbuf, 0, len);
36 
37          }
38 
39          System.out.println(sb.toString());
40 
41         
42 
43      }
44 
45 }

 

注意:

[1]win平台默認的utf8編碼的文本性文件帶有BOM,java轉換流寫入的utf8文件不帶BOM。所以用java讀取手動創建的utf8文件會出現一點亂碼(?hello中國,?是bom導致的)《詳情見下篇文章》

[2]一句話:用字符集編碼,一定用字符集解碼!!

 

總結:

FileReader = InputStreamReader + GBK

 1 packagecn.sxt07.outputstreamwriter;
 2 
 3  
 4 
 5 importjava.io.File;
 6 
 7 importjava.io.FileInputStream;
 8 
 9 importjava.io.FileReader;
10 
11 importjava.io.IOException;
12 
13 importjava.io.InputStreamReader;
14 
15  
16 
17 /**
18 
19  * 讀取一個gbk編碼的文本性文件
20 
21  */
22 
23 publicclass Test02 {
24 
25      public static void main(String[] args) throwsIOException {
26 
27         
28 
29         
30 
31          File file = new File("d:\\javatest\\f.txt");
32 
33         
34 
35          // 【1】建立管道
36 
37          /*
38 
39           * FileInputStream in = new FileInputStream(file);
40 
41           * InputStreamReader reader =  newInputStreamReader(in, "GBK");
42 
43           */
44 
45  
46 
47          FileReaderreader = newFileReader(file);
48 
49         
50 
51          char[] cbuf = newchar[2];
52 
53          intlen;
54 
55         
56 
57          StringBuildersb = newStringBuilder();
58 
59          while( (len=reader.read(cbuf))!=-1 ) {
60 
61               sb.append(cbuf, 0, len);
62 
63          }
64 
65         
66 
67          reader.close();
68 
69         
70 
71          System.out.println(sb.toString());
72 
73      }
74 
75 }

6. BufferedReader/BufferedWriter

BufferedReader繼承於Reader,提供了

read

read(char[] cbuf)

readLine() 用於讀取一行文本,實現對文本的高效讀取。

BufferedReader初始化時需要一個reader,本質上BufferedReader在reader的基礎上增加readLine()的功能。

 

BufferedWriter繼承於Writer,提供了

write

write(char[] cbuf)

write(string)

newLine() 寫入一個行分隔符。

 

需求:讀取一首詩

 1 public static void main(String[] args) throwsIOException {
 2 
 3                   
 4 
 5          // 按行讀取gbk文本性文件
 6 
 7         
 8 
 9          File file = new File("d:\\javatest\\i.txt");
10 
11         
12 
13          // 【1】創建管道
14 
15          FileReaderreader = newFileReader(file);
16 
17          BufferedReaderbr = newBufferedReader(reader);
18 
19         
20 
21          // 【2】讀取一行
22 
23          /*
24 
25          String line =  br.readLine();
26 
27          line =  br.readLine();
28 
29          line =  br.readLine();
30 
31          line =  br.readLine();
32 
33          */
34 
35         
36 
37          String line;
38 
39          while( (line=br.readLine()) != null) {
40 
41               System.out.println(line);
42 
43          }
44 
45      }

需求:以gbk編碼寫入一首詩到文件

 1 public static void main(String[] args) throwsIOException {
 2 
 3         
 4 
 5          File file = new File("d:\\javatest\\j.txt");
 6 
 7         
 8 
 9          // 【1】創建gbk管道
10 
11          FileWriterwriter = newFileWriter(file);
12 
13          BufferedWriterbw = newBufferedWriter(writer);
14 
15         
16 
17          // 【2】寫入一行
18 
19          bw.write("窗前明月光,");
20 
21          bw.newLine();
22 
23         
24 
25          bw.write("疑似地上霜。");
26 
27         
28 
29          // for win
30 
31          // bw.write("\r\n");
32 
33         
34 
35          // for unix/linux/mac
36 
37          // bw.write("\n");
38 
39         
40 
41          bw.write("舉頭望明月,");
42 
43          bw.newLine();
44 
45         
46 
47          // 【3】flush
48 
49          bw.flush();
50 
51         
52 
53          // 【4】關閉管道
54 
55          bw.close();
56 
57          writer.close();
58 
59      }

 

 需求:以utf8編碼高效寫入文件

 1 /**
 2 
 3  * 以utf8寫入一首詩
 4 
 5  * @author Administrator
 6 
 7  *
 8 
 9  */
10 
11 public class Test02 {
12 
13      public static void main(String[] args) throwsIOException {
14 
15         
16 
17          File file = new File("d:\\javatest\\j-utf8.txt");
18 
19         
20 
21          // 【1】創建utf8管道
22 
23          FileOutputStream out = newFileOutputStream(file);
24 
25          OutputStreamWriter writer = newOutputStreamWriter(out, "UTF-8");
26 
27          BufferedWriter bw = newBufferedWriter(writer);
28 
29         
30 
31          // 【2】寫入一行
32 
33          bw.write("窗前明月光,");
34 
35          bw.newLine();
36 
37         
38 
39          bw.write("疑似地上霜。");
40 
41         
42 
43          // for win
44 
45          bw.write("\r\n");
46 
47         
48 
49          // for unix/linux/mac
50 
51          // bw.write("\n");
52 
53         
54 
55          bw.write("舉頭望明月,");
56 
57          bw.newLine();
58 
59         
60 
61          // 【3】flush
62 
63          bw.flush();
64 
65         
66 
67          // 【4】關閉管道
68 
69          bw.close();
70      out.close();
71          writer.close();
72 
73      }
74 
75 }

 

需求:以utf-8編碼高效讀取文件

 1 package bufferedreader;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.File;
 6 import java.io.FileInputStream;
 7 import java.io.FileNotFoundException;
 8 import java.io.FileOutputStream;
 9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.io.OutputStreamWriter;
12 
13     //以utf-8讀取一首詩
14 public class Test01 {
15     public static void main(String[]args) throws FileNotFoundException,IOException{
16         File file=new File("f:\\javatest\\f.txt");
17         
18         FileInputStream in=new FileInputStream(file);
19         InputStreamReader reader=new InputStreamReader(in,"utf-8");
20         BufferedReader br=new BufferedReader(reader);
21         
22         String line;
23         while( (line=br.readLine())!=null){
24             System.out.println(line);
25         }
26         
27         
28         in.close();
29         reader.close();
30         br.close();
31         
32         
33     }
34 }

7.  標准輸入輸出流

1) 標准輸入流

源數據源是標准輸入設備(鍵盤、鼠標、觸摸屏)等輸入設備。在java中用System.in 得到一個InputStream字節輸入流。

 

需求:在控制台輸入一句話,然后原樣輸出

 1 public static void main(String[] args) throws IOException {
 2 
 3          // 需求:輸入一句話,然原樣輸出
 4 
 5          InputStream in = System.in;
 6 
 7         
 8 
 9          byte[] buf = newbyte[1024];
10 
11          intlen;
12 
13          // buf中包含回車和換行
14 
15          len = in.read(buf);
16 
17         
18 
19          String str = new String(buf, 0, len);
20 
21          // System.out.println(Arrays.toString(buf));
22 
23          System.out.println(str);
24 
25      }

 

 注意:

 標准輸入流以字節流流入內存,如果在控制台中輸入字符,字符以默認編碼(win簡體:gbk)編碼成字節進入標准輸入流。

 1 public static void main(String[] args) throws IOException {
 2 
 3          // 需求:從控制台高效讀取一行數據。把一首詩寫入文件。
 4 
 5         
 6 
 7          InputStream in = System.in;
 8 
 9          InputStreamReader reader = new InputStreamReader(in, "GBK");
10 
11          BufferedReader br = new BufferedReader(reader);
12 
13         
14 
15          File file = new File("d:\\javatest\\k.txt");
16 
17          FileWriter writer = new FileWriter(file);
18 
19          BufferedWriter bw = new BufferedWriter(writer);
20 
21         
22 
23          String end = "bye";
24 
25          while(true) {
26 
27               String line = br.readLine();
28 
29               if(line.equals(end)) {
30 
31                    break;
32 
33               }
34 
35              
36 
37               bw.write(line);
38 
39               // bw.newLine();
40 
41          }
42 
43         
44 
45          bw.flush();
46 
47         
48 
49          bw.close();
50 
51          writer.close();
52 
53         
54 
55      }

2)   標准輸出流(PrintStream)

數據目的地是標准輸出設備(顯示器)等輸出設備。在java中用System.out得到一個PrintStream 字節輸出流(字節打印流)。提供了更強大的

print

println

打印方法用於打印各種數據類型。

 

需求:讀取文件,顯示到標准輸出設備

 1 public static void main(String[] args) throws IOException {
 2 
 3         
 4 
 5          Filefile = new File("d:\\javatest\\k.txt");
 6 
 7         
 8 
 9          FileReader reader = new FileReader(file);
10 
11          BufferedReader br = new BufferedReader(reader);
12 
13         
14 
15          PrintStreamps = System.out;
16 
17         
18 
19          String line;
20 
21          while( (line=br.readLine())!=null ) {
22 
23               ps.println(line);
24 
25          }
26 
27      }

 

PrintStream 打印的所有字符都使用平台的默認字符編碼轉換為字節。

 1 public static void main(String[] args) throws IOException {
 2 
 3         
 4 
 5         
 6 
 7          String str = "hello中國";
 8 
 9          byte[] buf = str.getBytes("utf-8");
10 
11         
12 
13          PrintStream ps = System.out;
14 
15          ps.write(buf);
16 
17         
18 
19      }

 

8.  字符打印流PrintWriter

PrintWriter繼承Writer

數據目的地是標准輸出設備(顯示器)等輸出設備。在java中用System.out得到一個PrintSWriter 字符輸出流(字符打印流)。提供了更強大的

print

println

writer(String str)

打印方法用於打印各種數據類型。

9. Scanner

通過scanner掃描文件、字節流等

 1 public static void main(String[] args) throws IOException {
 2 
 3         
 4 
 5          // 掃描平台默認編碼的文件
 6 
 7          /*File file = new File("d:\\javatest\\j.txt");
 8 
 9          Scanner sc = new Scanner(file);
10 
11          */
12 
13         
14 
15          // 掃描指定編碼的文件
16 
17          Scanner sc = new Scanner(new FileInputStream(new File("d:\\javatest\\j-utf8.txt")), "UTF-8");
18 
19         
20 
21          String line;
22 
23          while (sc.hasNextLine()) {
24 
25               line = sc.nextLine();
26 
27               System.out.println(line);
28 
29          }
30 
31         
32 
33      }

 

 10. 序列化

把內存中的對象永久保存到硬盤的過程稱為對象序列化,也叫做持久化。

把硬盤持久化的內存恢復的內存的過程稱為對象反序列化。

 

1)    Serializable

類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化,並拋出異常

Exception in thread "main" java.io.NotSerializableException: cn.sxt05.serializable.Student

     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)

     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

     at cn.sxt05.serializable.Test01.main(Test01.java:22)

 Serializable接口沒有方法或字段,僅用於標識可序列化的語義

public class Student implements Serializable{

// 。。。

 

2)  序列化對象

ObjectOutputStream繼承於OutputStream,專門用於把對象序列化到本地。提供了

writeXXX

writeObject() 用於寫入一個對象

 1 public static void main(String[] args) throws IOException {
 2 
 3        
 4 
 5         Studentstu = new Student("001", "大狗", 20, Gender.男);
 6 
 7        
 8 
 9         /**
10 
11          *  方案1:取stu所有的屬性,通過特定的字符串(-),把各個屬性值連接起來
12 
13          *  001-大狗-20-男
14 
15          */
16 
17        
18 
19         File file = new File("d:\\javatest\\l.txt");
20 
21         FileOutputStream out = new FileOutputStream(file);
22 
23         ObjectOutputStream oos = new ObjectOutputStream(out);
24 
25        
26 
27         oos.writeObject(stu);
28 
29        
30 
31         oos.close();
32 
33         out.close();
34 
35     }

3)    反序列化對象

ObjectInputStream繼承於InputStream ,專門用於把本地持久化內容反序列化到內存,提供了

readXXX

readObject() 用於讀取一個序列化內容並返回一個對象。

 

 1 public static void main(String[] args) throws IOException, ClassNotFoundException {
 2 
 3         
 4 
 5          File file = new File("d:\\javatest\\l.txt");
 6 
 7         
 8 
 9         
10 
11          FileInputStream in = new FileInputStream(file);
12 
13          ObjectInputStreamois = newObjectInputStream(in);
14 
15         
16 
17          Student student = (Student) ois.readObject();
18 
19          System.out.println(student.getId());
20 
21          System.out.println(student.getName());
22 
23          System.out.println(student.getAge());
24 
25          System.out.println(student.getGender());
26 
27         
28 
29          ois.close();
30 
31          in.close();
32 
33      }

 

4) 序列化版本

當序列化完成后,后期升級程序中的類(Student),此時再反序列化時會出現異常。

Exception in thread "main" java.io.InvalidClassException: cn.sxt05.serializable.Student; local class incompatible: stream classdesc serialVersionUID = -6288733824962181189, local class serialVersionUID = 1690603786167234505

     at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)

     at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1876)

     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745)

     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2033)

     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)

     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)

     at cn.sxt05.serializable.Test02.main(Test02.java:16)

 

異常原因:序列化流的serialVersionUID和升級后類的版本不匹配。

 

解決方案:給Student類加序列化版本號,有兩種方式

 

 

 

default serial version ID 生成默認的serial version ID 一般值都是1L。

generatedserialversion ID根據當前類的屬性、方法生成一個唯一ID。

 

public class Student implements Serializable {

 

     private static final long serialVersionUID = -1003763572517930507L;

 

 

5)   transient

開發過程中,如果想忽略某些字段不讓其序列化時,可以使用transient修飾。

 1 public class Student implements Serializable {
 2 
 3  
 4 
 5     private static final long serialVersionUID = 7222966748321328300L;
 6 
 7  
 8 
 9     private String id;
10 
11     private transient String name;
12 
13     private transient int age;
14 
15     private Gender gender;
16 
17     private String phone;

 

 

11.  DataInputStream/DataOutputStream

DataOutputStream 繼承OutputStream,專門用於把基本java數據類型寫入輸出流。提供了writeXXX 寫入基本java數據類型。

 

DataInputStream繼承於InputStream,允許應用程序以與機器無關方式從底層輸入流中讀取基本 Java 數據類型。

 

DataInputStream/DataOutputStream特別適合讀取/寫入在網絡傳輸過程中的數據流。

 

寫入基本java數據類型

 1 public static void main(String[] args) throws IOException {
 2 
 3         
 4 
 5          File file = new File("d:\\javatest\\n.txt");
 6 
 7          FileOutputStream out= new FileOutputStream(file);
 8 
 9          DataOutputStreamdos = newDataOutputStream(out);
10 
11         
12 
13          dos.writeInt(10);
14 
15          dos.writeUTF("hello中國");
16 
17         
18 
19          dos.close();
20 
21          out.close();
22 
23         
24 
25          System.out.println("寫入完成");
26 
27         
28 
29      }

 

讀取基本java數據類型

 1 public static void main(String[] args) throws IOException {
 2 
 3        
 4 
 5         File file = new File("d:\\javatest\\n.txt");
 6 
 7         FileInputStream in = new FileInputStream(file);
 8 
 9         DataInputStream dis = new DataInputStream(in);
10 
11        
12 
13         inta = dis.readInt();
14 
15         String str = dis.readUTF();
16 
17        
18 
19         System.out.println(a);
20 
21         System.out.println(str);
22 
23        
24 
25     }

 

注意:

以什么順序寫入基本java數據類型,就以什么順序讀取基本java數據類型。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM