Java基礎 IO流——第四部分

 

 

新博客地址:Temijava

第一講:IO流(對象的序列化)git

一,對象序列化的概念:將堆內存中的對象存入硬盤,保留對象中的數據,稱之爲對象的持久化(或序列化)。github

               ========被序列化對象必須實現 Serializable 接口,接口Serializable中沒有方法,稱之爲標記接口===========web

==============靜態成員,和被transient 修飾的成員沒法被序列化。靜態成員屬於類級別的,因此不能序列化這裏的不能序列化的意思,是序列化信息中不包含這個靜態成員域你這個測試成功,是由於你都在同一個機器(並且是同一個進程),由於你這個jvm已經把count加載進來了,因此你獲取的是加載好的count,若是你是傳到另外一臺機器或者你關掉程序重寫寫個程序讀入test.obj,此時由於別的機器或新的進程是從新加載count的,因此count信息就是初始時的信息。====================數組

二,ObjectInputStream和ObjectOutputStream類的瞭解:dom

    1. ObjectOutputStream構造方法:public ObjectOutputStream(OutputStream out)  throws IOException
    2. ObjectInputStream  特有方法:public final Object  readObject()  throws IOException,  ClassNotFoundException            從 ObjectInputStream 讀取對象。
    3. ObjectOutputStream 特有方法:public final void writeObject (Object obj)  throws IOException 將指定的對象寫入 ObjectOutputStream。

三,序列化操做步驟:jvm

    1. 被序列化對象實現Serializable接口
    2. 肯定類中的serialVersionUID。=========序列化運行時使用一個稱爲 serialVersionUID的版本號與每一個可序列化類相關聯,用於驗證序列化對象的發送者和接收者是否爲同一對象。若是接收者加載的該對象的類的 serialVersionUID與對應的發送者的類的版本號不一樣,則反序列化將會致使 InvalidClassException。可序列化類能夠經過聲明名爲"serialVersionUID"的字段(該字段必須是靜態 (static)、最終 (final)的 long 型字段)顯式聲明其本身的serialVersionUID=========
    3. 建立對象寫入流,與文件關聯。           ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/obj.txt"));
    4. 經過寫入writeObject(Object obj)方法,將對象做爲參數傳入,便可寫入文件。oos.writeObject(obj);

四,代碼練習:ide

 

 1 import java.io.*;
 2 
 3 public class ObjectStreamDemo {
 4         public static void main(String[] args) {
 5             //聲明並實例化被序列化對象
 6             Person per = new Person("lisi",23,01,"ss");
 7             
 8             //序列化對象
 9             try {
10                 myObjectStream_Write(per);
11             } catch (FileNotFoundException e) {
12                 System.out.println("文件沒有找到"+e.toString());
13             } catch (IOException e) {
14                 System.out.println("序列化發生錯誤!"+e.toString());
15             }
16             
17             //接收讀取的對象
18             Person per2=null;
19             
20             //反序列化對象
21             try {
22                   per2 = (Person)myObjectStream_Reader();
23             } catch (FileNotFoundException e) {
24                  System.out.println("序列還文件不存在"+e.toString());
25             } catch (ClassNotFoundException e) {
26                 System.out.println("類文件沒有找到"+e.toString());
27             } catch (IOException e) {
28                 System.out.println("讀取發生錯誤"+e.toString());
29             }
30             
31             System.out.println(per2);
32         }
33         
34         
35         //自定義序列化 方法,將對象序列化到硬盤上
36         public static void myObjectStream_Write(Object obj) throws FileNotFoundException, IOException{
37             
38             //聲明序列化輸出流對像。並於文件相關聯
39             ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/obj.txt"));
40             
41             //將對象序列化到硬盤上
42             oos.writeObject(obj);
43             
44             //關閉流
45             oos.close();
46         }
47         
48         
49         //自定義讀取序列化對象方法
50         public static Object myObjectStream_Reader() throws FileNotFoundException, IOException, ClassNotFoundException{
51             
52             //聲明序列化輸入流,並於文件關聯
53             ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/obj.txt"));
54             
55             
56             //讀入被序列化的對象
57             Object object = ois.readObject();
58             
59             //關閉流
60             ois.close();
61             
62             return object;
63             
64         }
65 }

 

Person 類:函數

 1 import java.io.Serializable;
 2 
 3 
 4 //定義Person類實現Serializable接口,代表能夠被序列化
 5 public class Person implements Serializable{
 6        
 7     //定義serialVersionUID 代表版本號
 8     private static final long serialVersionUID = 1L;
 9     
10     //定義類成員
11     private String name;
12     private int age;
13     
14     //transient修飾符修飾的成員不能夠被序列化
15     transient int id;
16     
17     //靜態成員不能夠被序列化
18     static String country="aa";
19     
20     
21     //定義構造方法
22     public Person(String name,int age,int id,String country){
23         this.name=name;
24         this.age=age;
25         this.id=id;
26         this.country=country;
27     }
28     
29     @Override
30     public String toString(){
31         return "name:"+name+"---"+"age:"+age+"----"+"id:"+id+"----"+"country"+country;
32     }
33 
34 }

 

 

第二講:IO流(管道流)工具

一,管道流:PipedInputStream 和 PipedOutputStream  (輸入輸出能夠直接進行鏈接,不用再借助數組或集合等容器進行臨時存儲。經過結合線程使用)

    1. public class PipedInputStream  extends InputStream      管道輸入流應該鏈接到管道輸出流;管道輸入流提供要寫入管道輸出流的全部數據字節。
      1. 構造方法:public PipedInputStream()   建立還沒有鏈接的 PipedInputStream。在使用前必須將其鏈接到 PipedOutputStream
      2. 構造方法:public PipedInputStream(int pipeSize)  建立一個還沒有鏈接的 PipedInputStream,並對管道緩衝區使用指定的管道大小。在使用前必須將其鏈接到 PipedOutputStream
      3. 構造方法:public PipedInputStream(PipedOutputStream src,int pipeSize) throws IOException  建立一個 PipedInputStream,使其鏈接到管道輸出流 src,並對管道緩衝區使用指定的管道大小。寫入 src 的數據字節可用做此流的輸入。
      4. 方法:public void connect(PipedOutputStream src) throws IOException    使此管道輸入流鏈接到管道輸出流 src。若是此對象已經鏈接到其餘某個管道輸出流,則拋出 IOException
    2. public class PipedOutputStreamextends OutputStream     能夠將管道輸出流鏈接到管道輸入流來建立通訊管道。管道輸出流是管道的發送端。
      1. 構造方法:public PipedOutputStream()       建立還沒有鏈接到管道輸入流的管道輸出流。必須在使用以前將管道輸出流鏈接到管道輸入流(既可由接收者鏈接,也可由發送者鏈接)。
      2. 構造方法:public PipedOutputStream(PipedInputStream snk) throws IOException    建立鏈接到指定管道輸入流的管道輸出流。寫入此流的數據字節稍後將用做 snk 的輸入。
      3. 方法:public void connect(PipedInputStream snk)  throws IOException    將此管道輸出流鏈接到接收者。若是此對象已經鏈接到其餘某個管道輸入流,則拋出 IOException

二,操做步驟:

    1. 先建立一個讀和寫的兩個類,實現Runnable接口,由於是兩個不一樣的線程,覆蓋run方法。========注:線程的異常要在內部處理=========
    2. 建立兩個管道流,並用connect()方法將兩個流鏈接
    3. 將管道流綁定到線程。
    4. 建立線程並執行。

三,代碼練習:

 

  1 import java.io.*;
  2 
  3 //定義一個類,實現啓動一個線程,次線程包括一個讀的管道劉
  4 class Read implements Runnable{
  5     private PipedInputStream in;
  6     public Read(PipedInputStream in){
  7         this.in = in;
  8     }
  9     
 10     @Override
 11     
 12     //覆寫方法
 13     public void run(){
 14         
 15            //接受輸入數據
 16            byte buff[] = new byte[1024];
 17            
 18            
 19            //記錄數據長度
 20            int len=0;
 21            
 22            
 23            //循環接受數據
 24            while(true){
 25                try{
 26                    
 27                    //嘗試讀取數據
 28                    len = in.read(buff);
 29                    
 30                    //判斷是否結束
 31                    if("over".equals(new String(buff,0,len-2)))
 32                        break;
 33                    
 34                    //輸出用戶輸入的內容
 35                    System.out.println("管道讀取內容爲:"+new String(buff,0,len)+len);
 36                }catch(IOException e){
 37                    System.out.println("讀取異常"+e.toString());
 38                }
 39            }
 40            
 41            //給出運行完畢提示
 42            System.out.println("運行完畢");
 43     }
 44 }
 45 
 46 //定義一個類,實現啓動一個線程,此線程包括一個寫的管道流
 47 class Write implements Runnable{
 48     
 49     //聲明管道流對象
 50     private PipedOutputStream out;
 51     
 52     //構造方法
 53     public Write(PipedOutputStream out){
 54         this.out = out;
 55     }
 56     
 57     @Override
 58     
 59     //覆寫方法
 60     public void run(){
 61         
 62            //接受管道數據
 63            byte buff[] = new byte[1024];
 64            
 65            int len=0;
 66            
 67            
 68            //循環讀取
 69            while(true){
 70                try{
 71                    len=System.in.read(buff);
 72                    
 73                    
 74                    //輸出數據
 75                    out.write(buff, 0, len);
 76                    
 77                    //判斷是否結束
 78                    if("over".equals(new String (buff,0,len-2)))
 79                        break;
 80                }catch(IOException e){
 81                    System.out.println("管道讀取流發生異常"+e.toString());
 82                }
 83            }
 84            
 85            //給出結束提示
 86            System.out.println("運行完畢");
 87            
 88     }
 89 }
 90 public class PipedStreamDemo {
 91              public static void main(String[] args) {
 92                  
 93                         //建立 管道流對象做爲參數
 94                         PipedInputStream pis = new PipedInputStream();
 95                         PipedOutputStream pos = null;
 96                         
 97                         //將管道流相鏈接
 98                         try {
 99                             pos = new PipedOutputStream(pis);
100                         } catch (IOException e) {
101                             // TODO Auto-generated catch block
102                             e.printStackTrace();
103                         }
104                         
105                         //建立線程
106                         Thread t1 = new Thread(new Read(pis));
107                         Thread t2 = new Thread(new Write(pos));
108                         
109                         
110                         //啓動線程
111                         t1.start();
112                         t2.start();
113             }
114 }

 

第三講:IO流(RandomAccessFile)

一,RandomAccessFile 類的簡單瞭解。

      1. 類的聲明:public class RandomAccessFileextends Object  implements DataOutput, DataInput, Closeable  此類的實例支持對隨機訪問文件的讀取和寫入。
      2. 類的說明:
        1. 該類不算是IO體系中的子類,而是直接繼承Object,可是它是IO包成員,由於它具有讀寫功能,內部封裝了一個數組,且經過getFilePointer方法獲取指針位置,來對數組的元素進行操做,同時可經過seek方法改變指針的位置。
        2. 能夠完成讀寫的原理:內部封裝了字節輸入流和輸出流。
      3. 構造方法:public RandomAccessFile(File file, String mode) throws FileNotFoundException    建立從中讀取和向其中寫入(可選)的隨機訪問文件流,該文件由 File 參數指定。
      4. 構造方法:public RandomAccessFile(String name, String mode) throws FileNotFoundException   建從中讀取和向其中寫入(可選)的隨機訪問文件流 ====注:由構造方法能夠看出該類只能操做文件。且操做文件包括模式=====
      5. 方法:public long length() throws IOException    按字節測量的此文件的長度。
      6. public void seek(long pos) throws IOException    設置到此文件開頭測量到的文件指針偏移量,在該位置發生下一個讀取或寫入操做。===注:能夠向前和向後尋找====
      7. public int skipBytes(int n) throws IOException    嘗試跳過輸入的 n 個字節以丟棄跳過的字節。返回:跳過的實際字節數。===注:只能夠往前跳不能夠日後跳=====

=====注:關於讀寫模式的說明:若是模式爲只讀r,則不會建立文件,會去讀一個已存在的文件,若文件不存在,則會出現異常。若是模式爲讀寫rw,且該對象的構造函數要操做的文件不存在,會自動建立;若是存在,則不會覆蓋====

二,RandomAccessFile類的特色:

      1. 同一個類既有讀方法也有寫方法。
      2. 只能操做文件。
      3. 能夠實現對文件的隨機讀寫。

三,代碼練習:

 1 package com.examp.ch18;
 2 //需求:使用RandomAccessFileDemo進行讀寫操做
 3 
 4 import java.io.*;
 5 public class RandomAccessFileDemo {
 6     
 7     public static void main(String[] args)throws IOException {
 8         
 9         //建立文件對象
10         File file =new File("E:/test.txt");
11 
12         //寫數據
13         writeFile(file);
14 
15         //讀數據
16         readFile(file);
17 
18     }
19 
20     //讀取指定文件中的數據
21     public static void readFile(File file)throws IOException{
22         
23         
24         //建立隨機讀寫對象,指定文件打開方式爲只讀
25         RandomAccessFile raf=new RandomAccessFile(file,"r");
26         
27         //設置指針位置
28         raf.seek(8);
29 
30         //讀取四個字節存入
31         byte[] by=new byte[4];
32         
33         
34         //讀數據
35         raf.read(by);
36         
37         
38         //將存入數據的字節數組轉換爲字符串
39         String name=new String(by);
40         
41         
42         //讀取年齡
43         int age=raf.readInt();
44         
45         System.out.println("name="+name+"age="+age);
46 
47         //關閉流對象
48         raf.close();
49     }
50 
51     //建立方法將數據寫入指定文件中
52     public static void writeFile(File file)throws IOException{
53         
54         //建立對象,文件打開方式爲讀寫
55         RandomAccessFile raf=new RandomAccessFile(file,"rw");
56         
57         //寫入姓名
58         raf.write("張三".getBytes());
59         
60         
61         //寫入年齡,這裏調用了寫一個int方法
62         raf.writeInt(23);
63 
64         raf.write("李四".getBytes());
65         raf.writeInt(100);
66       
67         //改變指針位置,改變第一個對象的值
68         raf.seek(8*0);
69         raf.write("小三".getBytes());
70         raf.writeInt(3);
71 
72         
73         //改變指針位置
74         raf.skipBytes(8*2);
75         raf.write("王五".getBytes());
76         raf.writeInt(5);
77 
78         //關閉流
79         raf.close();    
80     }
81 }

 

 

第四講:IO流(操做基本數據類型的流對象DataStream)

一,ByteArrayInputStream和ByteArrayOutputStream 類的簡單瞭解:

      1. ByteArrayInputStream 在構造時,須要接受數據源。。並且數據源是一個字節數組。
      2. ByteArrayOutputStream 在構造時,不須要指定數據源,由於在其內部已經封裝的可變長度的字節數組。
      3. 這兩個流對象操做的都是數組,沒有使用系統資源,因此不須要關閉。
      4. 基本思想:用流的思想操做數組。
      5. ByteArrayOutputStream  方法:public void writeTo(OutputStream out)  throws IOException         將此 byte 數組輸出流的所有內容寫入到指定的輸出流參數中。==注:此方法拋出異常。===

二,對應的字符操做類:CharArrayReader和CharArrayWriter

        對應的字符串操做類: StringReader和StringWriter

三,代碼練習:

 1 import java.io.*;
 2 
 3 public class ByteArrayInputStreamDemo {
 4            public static void main(String[] args) {
 5                
 6                //定義字節操做輸入流,源爲一個字符串的字節數組形式
 7                ByteArrayInputStream bais=new ByteArrayInputStream("abcdef".getBytes());
 8                
 9                //定義字節操做輸出流
10                ByteArrayOutputStream baos=new ByteArrayOutputStream();
11                
12                //接受讀入的內容
13                int by=0;
14                
15                //循環讀取寫入內容
16                while((by = bais.read())!=-1){
17                    baos.write(by);
18                }
19                
20                //輸出字節操做流寫入的內容
21                System.out.println(baos.toString());
22         }
23 }

 

第五講:IO流(ByteArrayStream)

 

 

第六講:IO流(轉換流的字符編碼)

一,字符概述:

    1. Java IO 操做中能夠加入字符編碼表的四個對象:
      1. 轉換流:InuputStreamReader和OutputStreamWriter
      2. 打印流:PrintStream和PrintWriter    =====注:只有輸出流=====

二,編碼表的由來:計算機只能識別二進制數據,早期由來是電信號。爲了方便應用計算機,讓它能夠識別各個國家的文字。就將各個國家的文字用數字來表示,並一一對應,造成一張表。這就是編碼表。

  1. 常見的編碼表:ASCII:美國標準信息交換碼錶。用一個字節的7位表示
  2. IOS8859-1:拉丁碼錶;歐洲碼錶。用一個字節的8位表示。====注:打頭爲 1======
  3. GB2312:中國的中文編碼表(早期)兩個字節表示一個字符(6-7千字符)。====注:打頭的是兩個高位爲1的兩個字節編碼。===
  4. GBK:中國的中文編碼表升級,融合了更多的中文文字字符。(兩萬字符左右)。====注:打頭的是兩個高位爲1的兩個字節編碼。===
  5. Unicode:國際標準碼,融合了多種文字。全部文字都用兩個字節來表示,Java語言使用的就是unicode。
  6. UTF-8:最多用三個字節表示一個字符的編碼表,根據字符所佔內存空間不一樣,分別用一個、兩個、三個字節來編碼。

    1. UTF-8編碼格式:一個字節:0開頭
    2.  兩個字節:字節一  ---> 110    位數:10 ~ 6 。字節二  ---> 10     位數:5 ~ 0
    3. 三個字節:字節一  ---> 110    位數:15 ~ 12 字節二  ---> 10     位數:11 ~ 6 字節三 ---> 10     位數:5 ~ 0

 

三,代碼練習:

  1 import java.io.*;
  2 
  3 
  4 public class EncodingStream {
  5              public static void main(String[] args) {
  6                  
  7                  //分別建立兩個文件對象,用來存儲兩種編碼格式的數據
  8                  File file_GBK = new File("E:/gbk.txt");
  9                  File file_UTF = new File("E:/utf.txt");
 10                  
 11                  //分別按照兩種編碼格式寫入數據
 12                  try {
 13                     writeText_GBK(file_GBK);
 14                     writeText_UTF(file_UTF);
 15                 } catch (IOException e) {
 16                     System.out.println("寫入文件發生異常"+e.toString());
 17                 }
 18                  
 19                  
 20                  //按照兩種編碼格式分別讀取兩個文件
 21                  try {
 22                      
 23                      //正常
 24                      System.out.println("正常:");
 25                     readText_GBK(file_GBK);
 26                     //亂碼
 27                     System.out.println("亂碼");
 28                     readText_GBK(file_UTF);
 29                     //正常
 30                     System.out.println("正常:");
 31                     readText_UTF(file_UTF);
 32                     //亂碼
 33                     System.out.println("亂碼");
 34                     readText_UTF(file_GBK);
 35                 } catch (IOException e) {
 36                     System.out.println("讀入文件發生錯誤"+e.toString());
 37                 }
 38                  
 39             }
 40              
 41              
 42              //定義方法將數據按GBK編碼寫入文件
 43              public static void writeText_GBK(File file) throws IOException{
 44                  
 45                     //建立輸出字符流,使用指定的文件,以及編碼
 46                     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"gbk");
 47                     
 48                     
 49                     //寫入內容
 50                     osw.write("黑馬訓練營");
 51                     
 52                     //刷新流
 53                     osw.flush();
 54                     //關閉流
 55                     osw.close();
 56              }
 57              
 58              
 59              //定義方法,將數據按照GBK編碼從文件中讀入
 60              public static void readText_GBK(File file) throws IOException{
 61                  
 62                     //建立文件讀取字符流,使用指定的編碼,以及文件
 63                     InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"gbk");
 64                     
 65                     //接受讀入的字符
 66                     char ch[] = new char[1024];
 67                     
 68                     //標記讀入的字符數
 69                     int  len=0;
 70                     
 71                     //循環讀取打印
 72                     while((len=isr.read(ch))!=-1){
 73                         System.out.println(new String(ch,0,len));
 74                     }
 75                     //關閉流操做
 76                     isr.close();
 77              }
 78              
 79              
 80              //定義方法,將數據按照UTF-8編碼寫入指定的文件
 81              public static void writeText_UTF(File file) throws IOException{
 82                  
 83                     //建立輸出字符流,使用指定的文件,以及編碼
 84                     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
 85                     
 86                     //寫出數據
 87                     osw.write("黑馬訓練營");
 88                     
 89                     osw.flush();
 90                     
 91                     osw.close();
 92              }
 93              
 94              
 95              //定義方法,將數據按照UTF-8編碼從指定文件讀入
 96              public static void readText_UTF(File file)throws IOException{
 97                     //建立文件讀取字符流,使用指定的編碼,以及文件
 98                     InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8");
 99                     
100                     //定義數組接受字符
101                     char ch[] = new char[1024];
102                     
103                     //標記
104                     int len=0;
105                     
106                     //循環讀取
107                     while((len=isr.read(ch))!=-1){
108                         System.out.println(new String(ch,0,len));
109                     }
110                     
111                     isr.close();
112              }
113 }

 

 

第七講:字符編碼

一,編碼和解碼

    1. 編碼:字符串變成字節數組       String  --->  byte[]  :srt.getBytes(charsetName)
    2. 解碼:字節數組變成字符串         byte[]   --->  String :newString(byte[],charsetName)

二,編碼和解碼的字符集轉換注意事項

      1. 若是編碼失敗,解碼就沒意義了。
      2. 若是編碼成功,解碼出來的是亂碼,,則需對亂碼經過再次編碼(用解錯碼的編碼表),而後再經過正確的編碼表解碼。針對於IOS8859-1是通用的。
      3. 若是用的是GBK編碼,UTF-8解碼,此時經過再次編碼後解碼的方式,就不能成功了,由於UTF-8也支持中文,在UTF-8解的時候,會將對應的字節數改變,因此不會成功。

 

三,代碼練習:

 1 import java.util.Arrays;
 2 
 3 public class EncodingDemo {
 4             public static void main(String args[]) throws Exception{
 5                 
 6                 //建立一個字符串
 7                 String s="您好";
 8                 //得到字符串的GBK 碼錶
 9                 byte[] b1 = s.getBytes("gbk");
10                 //輸出碼錶
11                 System.out.println(Arrays.toString(b1));
12                 //從新編碼
13                 String s1 = new String(b1,"gbk");
14                 
15                 System.out.println("s1="+s1);
16                 
17                 //獲取字符串的ISO8859-1碼錶
18                 byte[] b2 = s1.getBytes("ISO8859-1");
19                 //輸出碼錶
20                 System.out.println(Arrays.toString(b2));
21                 //從新編碼
22                 String s2 = new String (b2,"gbk");
23                 
24                 System.out.println(s2);
25             }
26 }

 

第八講:字符編碼-聯通

一,對於中文的」聯通「,這兩個字比較特別,它的二進制位正好是和在UTF-8中兩個字節打頭的相同,因此在文本文件中,若是單獨寫「聯通」或者和知足UTF-8編碼格式的字符一塊兒保存時,記事本就會用UTF-8來進行解碼動做,這樣顯示的就會是亂碼。

    解決辦法:在聯通前面加上任意中文字符。

二,代碼練習:

 

 1 import java.io.UnsupportedEncodingException;
 2 
 3 public class LianTongDemo {
 4             public static void main(String[] args) throws UnsupportedEncodingException {
 5                    String s = "聯通";
 6                    
 7                    byte[] bytes = s.getBytes("gbk");
 8                    
 9                    for(byte b : bytes){
10                        System.out.println(Integer.toBinaryString(b&255));
11                    }
12             }
13 }

 

第九講:練習

一,需求分析:

                  有五個學生,每一個學生有3門課的成績,從鍵盤輸入以上數據(包括姓名,三門課成績輸入的格式:如:張三,30,40,60計算出總成績,並把學生的信息和計算出的總分數由高低順序存放在磁盤文件「stuinfo.txt」中

二,思路:

    1. 描述對象
    2. 定義一個可操做學生對象的工具類。 
    3. 經過獲取鍵盤錄入一行數據,並將該行中的信息取出封裝成學生對象。
    4. 由於學生有不少,那麼就須要存儲,使用到集合。由於要對學生的總分排序。因此可使用TreeSet。
    5. 將集合的信息寫入到一個文件中。

三,代碼練習:

 

  1 import java.io.*;
  2 import java.util.*;
  3 
  4 
  5 //學生類實現Comparable接口
  6 class Student implements Comparable<Student>{
  7     private String name;
  8     private int sx,yy,yw,sum;
  9     Student(String name,int sx,int yw,int yy){
 10         this.name=name;
 11         this.sx=sx;
 12         this.yw=yw;
 13         this.yy=yy;
 14         sum=sx+yw+yw;
 15     }
 16 
 17     //獲取總成績
 18     public int getSum(){
 19         return sum;
 20     }
 21 
 22     //獲取姓名
 23     public String getName()
 24     {
 25         return name;
 26     }
 27 
 28     //複寫compareTo方法
 29     public int compareTo(Student s)    {
 30         
 31         int num=new Integer(this.sum).compareTo(new Integer(s.sum));
 32         if(num==0)
 33             return this.name.compareTo(s.name);
 34         return num;
 35     }
 36     
 37     //複寫hashCode
 38     public int hashCode(){
 39         
 40         return name.hashCode()+sum*33;
 41     }
 42 
 43     //複寫equals
 44     public boolean equals(Object obj){
 45         
 46         if(!(obj instanceof Student))
 47             throw new ClassCastException("類型不匹配");
 48         Student s=(Student)obj;
 49         return this.name.equals(s.name)&&this.sum==s.sum;
 50     }
 51 
 52     
 53     //複寫toString
 54     public String toString(){
 55         return "Student["+name+","+sx+","+yw+","+yw+"]";
 56     }
 57 }
 58 
 59 //學生工具類
 60 class StudentTools{
 61     //從鍵盤讀取學生信息方法,以學生自身排序方式存入集合中
 62     public static Set<Student> getStudentInfo_1()throws IOException
 63     {
 64          return getStudentInfo_2(null);
 65     }
 66 
 67     //從鍵盤讀取學生信息方法,以比較器排序方式存入集合中
 68     public static Set<Student> getStudentInfo_2(Comparator<Student> cmp)throws IOException
 69     {
 70         //鍵盤錄入
 71         BufferedReader bis=
 72             new BufferedReader(new InputStreamReader(System.in));
 73         String info=null;
 74 
 75         //定義一個集合,用來存儲學生對象
 76         Set<Student> set=null;//---------
 77         if(cmp==null)
 78             set=new TreeSet<Student>();
 79         else
 80             set=new TreeSet<Student>(cmp);
 81 
 82         //讀取數據
 83         while((info=bis.readLine())!=null)
 84         {
 85 
 86             if("over".equals(info)) 
 87                 break;
 88 
 89             String[] in=info.split(",");
 90             //將學生對象存入集合中
 91             set.add(new Student(in[0],Integer.parseInt(in[1]),
 92                                     Integer.parseInt(in[2]),
 93                                     Integer.parseInt(in[3])));
 94         }
 95         bis.close();//關流
 96 
 97         return set;
 98     }
 99 
100     //把學生信息按照指定屬性寫入指定文件中
101     public static void writeToFile(Set<Student> set,File file)throws IOException
102     {
103         //關聯文件
104         BufferedWriter bw=new BufferedWriter(new FileWriter(file));
105 
106         //遍歷
107         for (Student stu : set)
108         {
109             //將學生信息寫入指定文件中
110             bw.write(stu.toString()+"\t");
111             bw.write(stu.getSum()+"");
112             bw.newLine(); 
113             bw.flush();
114         
115         }
116         
117         bw.close();//關流
118     }
119 }
120 
121 
122 public class  StudentInfoTest
123 {
124     public static void main(String[] args) 
125     {
126         //定義一個翻轉自身比較性的比較器
127         Comparator<Student> cmp=Collections.reverseOrder();
128         try
129         {
130             //指定文件
131             File file =new File("stdinfo.txt");
132     
133             //調用學生工具類的獲取信息方法,將信息存入集合中
134             Set<Student> set=StudentTools.getStudentInfo_2(cmp);
135 
136 
137             //將學生信息寫入指定文件中
138             StudentTools.writeToFile(set,file);
139         }
140         catch (IOException e)
141         {
142             throw new RuntimeException("學生信息獲取寫入失敗");
143         }    
144     }
145 }
相關文章
相關標籤/搜索