Java學習筆記之IO補充

左墾發表於2017-05-17

隨著對檔案學習的深入,我們開始學習到了關於對IO流的一些操作,主要是通過以下幾個類進行學習的
1.LineNumberReader
public class LineNumberReaderextends BufferedReader
跟蹤行號的緩衝字元輸入流。
對於它的使用主要用到兩個方法:
* public int getLineNumber():獲取行號
* public void setLineNumber(int lineNumber):設定起始行號
具體使用如下:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

    /**
            案例:讀取檔案,每次讀取一行列印並且加上行號
     *
     */

    public class LineNumberReaderDemo {
        public static void main(String[] args) throws IOException {
            LineNumberReader lnr = new LineNumberReader(new FileReader("copy.txt"));
            int lineNumber = lnr.getLineNumber();
            System.out.println(lineNumber);

        //  lnr.setLineNumber(3);

            String line;
            while((line = lnr.readLine()) != null){
                System.out.println(lnr.getLineNumber() + ":  " + line);
            }
        }
    }

2.操作基本資料型別的流

  • 可以操作基本型別的流物件。
  • DataInputStream:讀資料
  • DataOutputStream:寫資料

  • 案例:給流中寫基本型別的資料,並且讀取
    注意:
  • 讀寫順序必須一致,否則資料有問題。
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;

    /**
    案例:給流中寫基本型別的資料,並且讀取
    注意:

    • 讀寫順序必須一致,否則資料有問題。
      *
      */

    public class DataOutputStreamDemo {
    public static void main(String[] args) throws IOException {
    //寫資料
    write();
    read();
    }

    private static void read() throws IOException {
        //DataInputStream:讀資料
        //建立物件:public DataInputStream(InputStream in)
        DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
    
        //讀資料了,按什麼順序寫入就必須按照什麼順序讀出來
        System.out.println(dis.readByte());
        System.out.println(dis.readShort());
        System.out.println(dis.readInt());
        System.out.println(dis.readLong());
        System.out.println(dis.readChar());
        System.out.println(dis.readFloat());
        System.out.println(dis.readDouble());
        System.out.println(dis.readBoolean());
    
        //關流
        dis.close();
    }
    
    private static void write() throws IOException {
        //public DataOutputStream(OutputStream out)
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
    
        //給流關聯的檔案中寫入基本型別的資料
        dos.writeByte(20);
        dos.writeShort(200);
        dos.writeInt(2000);
        dos.writeLong(20000L);
    
        dos.writeChar(97);
        dos.writeFloat(12.34F);
        dos.writeDouble(23.34);
        dos.writeBoolean(true);
    
        //關流
        dos.close();
    }
    

    }
    3.記憶體操作流:
    解決臨時資料儲存的問題。
    此類類有
    A.操作位元組陣列:ByteArrayInputStream,ByteArrayOutputStream
    B.操作字元陣列:CharArrayReader,CharArrayWrite
    C.操作字串:StringReader,StringWriter
    以ByteArrayInputStream類為例,它包含一個內部緩衝區,該緩衝區包含從流中讀取的位元組。內部計數器跟蹤read方法要提供的下一個位元組。關閉ByteArrayInputStream無效。此類中的方法在關閉此流後仍可被呼叫,而不會產生任何 IOException。
    ByteArrayOutputStream類實現了一個輸出流,其中的資料被寫入一個 byte 陣列。緩衝區會隨著資料的不斷寫入而自動增長。可使用 toByteArray() 和toString()獲取資料。關閉ByteArrayOutputStream無效。此類中的方法在關閉此流後仍可被呼叫,而不會產生任何 IOException。
    其他類和他們類似。
    4.列印流
    位元組列印流 PrintStream 為其他輸出流新增了功能,使它們能夠方便地列印各種資料值表示形式。它還提供其他兩項功能。與其他輸出流不同,PrintStream 永遠不會丟擲 IOException;而是,異常情況僅設定可通過 checkError方法測試的內部標誌。另外,為了自動重新整理,可以建立一個 PrintStream;這意味著可在寫入 byte 陣列之後自動呼叫 flush 方法,可呼叫其中一個 println 方法,或寫入一個換行符或位元組 (‘\n’)。PrintStream列印的所有字元都使用平臺的預設字元編碼轉換為位元組。在需要寫入字元而不是寫入位元組的情況下,應該使用 PrintWriter 類。

    字元列印流       PrintWriter
    

    特點:
    A:只能操作目的地,不能運算元據源
    B:可以操作任意型別的資料
    C:如果啟動了自動重新整理,能夠自動重新整理
    D:可以操作檔案的流
    下面用一個複製檔案的案例來證明一下PrintStream和PrintWriter的方便之處:
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;

    public class CopyJavaDemo {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new FileReader("d://TestTime.java"));
            PrintWriter pw = new PrintWriter(new FileWriter("TestTime2.java"), true);
    
            String len;
            while((len = br.readLine()) != null){
                pw.println(len);//1.寫資料 2.換行 3.重新整理
            }
    
            br.close();
            pw.close();
        }
    }
    

    5.標準輸入輸出流
    System類下有這樣的兩個成員變數:

    標準輸入流:
    public static final InputStream in

    案例1:利用標註輸入流進行鍵盤錄入,錄入後讀取流並列印在控制檯
    import java.io.IOException;
    import java.io.InputStream;

    public class SystemIn {
        public static void main(String[] args) throws IOException {
            //Scanner sc = new Scanner(System.in);底層還是輸入流
            InputStream is = System.in;//將鍵盤錄入封裝成輸入流
    
            int by;
            while((by = is.read()) != -1){
                System.out.print((char)by);
            }
    
            is.close();
        }
    }
    

    案例2:用IO流實現鍵盤錄入,一次讀取一行資料
    分析:
    InputStream is = System.in;
    BufferedReader是字元緩衝流,是對字元流進行高效操作的
    所以,引數必須是字元型別
    而我們現在有的是位元組型別的流
    請問:怎麼辦呢?轉換流
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

        public class SystemInDemo2 {
            public static void main(String[] args) throws IOException {
                //用io流實現鍵盤錄入
    
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
                System.out.println("請輸入姓名");
                String name = br.readLine();
                System.out.println(name);
                System.out.println("請輸入年齡");
                String age = br.readLine();
                System.out.println(age);
                br.close();
            }
        }
    

    標準輸出流:
    public static final PrintStream out

    案例:解析輸出語句System.out.println(“helloworld”);
    import java.io.PrintStream;

    public class SystemOutDemo {
        public static void main(String[] args) {
            PrintStream ps = System.out;
            ps.println(true);//等同於System.out.println();
        }
    }
    
    1. 合併流:
      SequenceInputStream類可以將多個輸入流串流在一起,合併為一個輸入流,因此,該流也被稱為合併流。

    構造:
    SequenceInputStream(InputStream s1, InputStream s2) :將s1和s2合併成一個輸入流,先讀取s1後讀取s2

    1. Properties(檢視api實現map介面本質是一個map集合)
      7.1
      Properties:Properties 類表示了一個持久的屬性集。屬性列表中每個鍵及其對應值都是一個字串。
      特點:Properties 可儲存在流中或從流中載入。
      案例:使用map集合的put方法給集合中儲存資料並且遍歷

    7.2
    Properties的特有功能:
    A:新增元素
    public Object setProperty(String key,String value)
    B:獲取元素
    public String getProperty(String key)
    public Set stringPropertyNames()
    案例:使用它的特有功能新增元素並遍歷

    7.3
    可以和IO流進行結合使用:
    把檔案中的資料載入到集合中。注意:檔案中的資料必須是鍵值物件形式的(例如:張傑=謝娜)。
    public void load(InputStream inStream)
    public void load(Reader reader)
    案例:建立一個鍵值對檔案,將檔案中的鍵值對載入到集合中,輸出集合

    把集合中的資料儲存到文字檔案中,並且是按照鍵值對形式儲存的。
    public void store(OutputStream out,String comments)
    public void store(Writer writer,String comments)
    案例:將建立的鍵值對集合載入到檔案中
    

案例:我有一個猜數字小遊戲的程式,請寫一個程式實現在測試類中只能用5次,
超過5次提示:遊戲試玩已結束,請付費。
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

    /**
     * 我有一個猜數字小遊戲的程式,請寫一個程式實現在測試類中只能用5次,
          超過5次提示:遊戲試玩已結束,請付費。
     */

    public class PropertiesDemo {
        public static void main(String[] args) throws Exception{
            Properties prop = new Properties();
            prop.load(new FileReader("count.txt"));

            Integer number = Integer.valueOf(prop.getProperty("count"));
            number++;
            if(number>2){
                System.out.println("試玩結束,請付費!");
                System.exit(0);
            }else{  
                prop.setProperty("count", String.valueOf(number)); 
                prop.store(new FileWriter("count.txt"), null);
                System.out.println("第"+number+"次試玩");
                GuessNumber.startGame();    
            }
        }
    }

相關文章