IO流

字節流(以字節爲單位)

  • 當不一樣的介質之間有數據交互的時候,JAVA就使用流來實現。
  • 數據源能夠是文件,還能夠是數據庫,網絡甚至是其餘的程序
  • 輸入流: InputStream 輸出流:OutputStream

字節輸入輸出流

  • 文件輸出流(FileOutputStream)java

    • OutputStream是字節輸出流,同時也是抽象類,只提供方法聲明,不提供方法的具體實現。數據庫

    • FileOutputStream 是OutputStream子類數組

    • 將數據從內存寫入到硬盤緩存

      import java.io.FileOutputStream;
      import java.io.IOException;
      
      public class FileOutputStream01 {
          public static void main(String[] args) throws IOException {
              //建立一個FileOutputStream對象,構造方法傳入寫入數據的文件
              FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt");
              //調用FileOutputStream對象中的方法write,將數據寫入文件
              fos.write(2333);
              //釋放資源,流的使用會佔用資源,使用完要將內存清空,提升程序效率
              fos.close();
          }
      }
    • 文件中一次寫入多個字節:
      write(byte[] b):若是寫入的第一個字節是正數(0-127),顯示時會查詢ASCII表;若是寫入的第一個字節是負數,那麼第一個字節和第二個字節會組成中文顯示,查詢系統默認碼錶(GBK)
      write(byte[] b, int off, int len)int off:數組b開始的索引;int len:寫入幾個字節網絡

    • 文件續寫:使用FileOutputStream中兩個參數的構造方法app

      FileOutputStream(String name, boolean append):append是續寫開關,當爲true時繼續在文件末尾追加寫數據,當爲false時建立新文件覆蓋原文件ide

  • 文件輸入流(FileInputStream)性能

    • InputStream是字節輸出流,同時也是抽象類,只提供方法聲明,不提供方法的具體實現。this

    • FileInputStream 是InputStream子類code

    • 將數據從硬盤寫入到內存

      import java.io.FileInputStream;
      import java.io.IOException;
      
      public class FileInputStream01 {
          public static void main(String[] args) throws IOException {
              //建立FileInputStream對象
              FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\b.txt");
              //調用read方法,讀取文件中的一個字節並返回,讀取到文件的末尾返回-1
              int read = 0;
              while ((read= fis.read()) != -1) {
                  System.out.println(read);
              }
              //釋放資源
              fis.close();
          }
      }
    • 文件中一次讀取多個字節:

      read(byte[] b): 從輸入流讀取必定數量的字節,並將其存儲在緩衝區數組b中

  • 複製文件(一讀一寫)

    package InputStream;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class CopyFile {
        public static void main(String[] args) throws IOException {
            long start = System.currentTimeMillis();
            FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\copy.jpg");
            FileInputStream fis = new FileInputStream("D:\\1.jpg");
            //使用數組緩衝區讀取多個字節寫入多個字節
            byte[] bytes = new byte[1024];
            int read = 0;
            while ((read = fis.read(bytes)) != -1){
                fos.write(bytes, 0, read);
            }
    
            //釋放資源,先關寫入再關讀取
            fos.close();
            fis.close();
            long end = System.currentTimeMillis();
            System.out.println("複製完成,用時:"+(end-start)+"ms");
        }
    }

字符流(以字符爲單位)

  • 當使用字節流讀取文本,遇到中文時可能不會顯示完整字符,由於中文可能佔用多個字節存儲
  • Java提供的字符流專門用於字符的形式讀取和寫入數據,專門用於處理文本文件
  • Reader是字符輸入流最頂層的父類,是一個抽象類
  • Writer是字符輸出流最頂層的父類,是一個抽象類

字符輸入輸出流

  • 文件字符輸入流(FileReader)

    • FileReader 是Reader子類

    • 將硬盤文件中的數據以字符的方式讀取到內存中

      import java.io.FileReader;
      import java.io.IOException;
      
      public class FileReaderDemo {
          public static void main(String[] args) throws IOException {
              //建立FileReader對象,構造方法中綁定數據源
              FileReader fr = new FileReader("IOAndProperties\\src\\OutputStream\\b.txt");
      
              //int read():讀取單個字符並返回
              //int read(char[] cbuf):一次讀取多個字符,並將數組存儲數組中
              char[] cbuf = new char[1024];
              int len = 0;
              while ((len = fr.read(cbuf)) != -1){
                  System.out.println(new String(cbuf, 0, len));
              }
              //釋放資源
              fr.close();
          }
      }
  • 文件字符輸出流(FileWriter)

    • FileWriter 是Writer子類

    • 將內存中的數據以字符的方式寫入文件中

    • 須要將內存緩衝區中的數據刷新到文件中

      import java.io.FileWriter;
      import java.io.IOException;
      
      public class FileWriterDemo {
          public static void main(String[] args) throws IOException {
              //建立FileWriter對象,構造方法中綁定數據目的地
              FileWriter fw = new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt");
      
              //調用write方法把數據寫入內存緩衝區(字符轉換爲字節的過程)
              //void write(int c):寫入單個字符
              //void write(char[] cbuf, int off, int len):一次寫入多個字符
              //void write(String str):寫入字符串
              //void write(String str, int off, int len):寫入字符串一部分
              char[] cbuf = {'你', '好', 'c', 'd'};
              String str = "陰陽師";
              fw.write(cbuf, 0, 3);
              fw.write(str, 0, 3);
              
              //使用FileWriter中的方法flush,把內存緩衝區中的數據刷新到文件中
              fw.flush();
              //釋放資源(也會先把內存緩衝區中的數據刷新到文件中)
              fw.close();
          }
      }

      flush和close方法的區別:flush刷新緩衝區,流對象能夠繼續使用;close先刷新緩衝區,而後通知系統釋放資源,流對象不能夠再被使用了

    • 文件續寫:使用FileWriter中兩個參數的構造方法

      FileWriter(String name, boolean append):append是續寫開關,當爲true時繼續在文件末尾追加寫數據,當爲false時建立新文件覆蓋原文件

Properties集合

  • Properties集合是一個雙列集合,key和value都默認是字符串

  • Properties類表示了一個持久屬性集,Properties可保存在流中也可從流中加載

  • Properties集合中的store方法把集合中的臨時數據持久化寫入到硬盤中保存

    傳入字節輸入流則不能保存中文,傳入字符輸入流則能夠保存中文

  • Properties集合中的load方法把硬盤中保存的文件(鍵值對)讀取到集合中使用

    傳入字節輸入流則不能讀取中文,傳入字符輸入流則能夠讀取中文

    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Properties;
    
    //使用properties中的store方法將臨時數據寫入硬盤中存儲
    public class Properties01 {
        public static void main(String[] args) throws IOException {
            //建立properties集合對象添加數據
            Properties date = new Properties();
            //建立字節/字符輸出流對象
            FileWriter fw = new FileWriter("IOAndProperties\\src\\properties\\pro.txt");
            //往集合中添加數據
            date.setProperty("追月神","打火");
            date.setProperty("八岐大蛇","輸出大佬");
            date.setProperty("山兔","拉條");
            date.setProperty("日和坊","奶媽");
            //使用store方法往硬盤中存儲數據,comments爲註釋,不能使用中文,通常用空字符串
            date.store(fw, "save date");
            fw.close();
        }
    }
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    
    //使用properties中的load方法讀取硬盤中的鍵值對數據
    //存儲鍵值對數據的文件中,鍵值默認鏈接符能夠是=,空格
    //存儲鍵值對數據的文件中,使用#進行註釋,被註釋的鍵值對將不被讀取
    public class PropertiesLoad {
        public static void main(String[] args) throws IOException {
            //建立Properties集合對象
            Properties date = new Properties();
            //使用load方法讀取保存鍵值對數據的文件
            date.load(new FileReader("IOAndProperties\\src\\properties\\pro.txt"));
            //遍歷Properties集合
            Set<String> set = date.stringPropertyNames();//將讀取的key存入Set集合中
            for (String key : set) {
                String value = date.getProperty(key);//根據key讀取value
                System.out.println(key+" "+value);
            }
        }
    }

緩衝流

字節流和字符流的弊端,在每一次讀寫的時候,都會訪問硬盤。 若是讀寫的頻率比較高的時候,其性能表現不佳。爲了解決以上弊端,採用緩衝流。 緩衝流在讀取的時候,會一次性讀較多的數據到緩存中,之後每一次的讀取,都是在緩存中訪問,直到緩存中的數據讀取完畢,再到硬盤中讀取。

  • 字節緩衝流:BufferedInputStreamBufferedOutputStream

  • 字符緩衝流:BufferedReaderBufferedWriter

  • 基本原理:建立流對象時,會建立一個內置的默認大小的緩衝區數組,經過緩衝區讀寫,減小系統IO次數,提升讀寫效率

字節緩衝流

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//字節緩衝輸出流
public class BufferedOutputStream01 {
    public static void main(String[] args) throws IOException {
        //建立一個FileOutputStream對象,構造方法傳入寫入數據的文件
        FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt");
        //建立BufferedOutputStream對象,構造方法中傳遞FileOutputStream對象
        BufferedOutputStream buff = new BufferedOutputStream(fos);
        //使用BufferedOutputStream中的write方法,將數據寫入內存緩衝區
        String str = "你好";
        buff.write(str.getBytes());
        //使用BufferedOutputStream中的flush方法將內部緩衝區的數據刷新到文件中
        buff.flush();
        //釋放資源(會先調用flush,上一步可省)
        buff.close();
    }
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

//字節緩衝輸入流
public class BufferedInputStream01 {
    public static void main(String[] args) throws IOException {
        //建立一個FileInputStream對象,構造方法傳入寫入數據的文件
        FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\a.txt");
        //建立BufferedInputStream對象,構造方法中傳遞FileInputStream對象
        BufferedInputStream buff = new BufferedInputStream(fis);
        //使用BufferedOutputStream中的read方法,讀取對象
        int len = 0;
        byte[] cbuf = new byte[1024];
        while ((len = buff.read(cbuf)) !=-1){
            System.out.println(new String(cbuf, 0, len));
        }
        //釋放資源
        buff.close();
    }
}

字符緩衝流

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

//字符緩衝輸出流
public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        //建立字符緩衝輸出流對象
        BufferedWriter bw = new BufferedWriter(new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
        //調用write方法寫入數據
        bw.write("陰陽師你好");
        //刷新緩衝區,釋放資源
        bw.flush();
        bw.close();
    }
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

//字符緩衝輸入流
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        //建立字符緩衝輸入流對象
        BufferedReader br = new BufferedReader(new FileReader("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
        //使用read或readline讀取數據,readline每次只讀取一行
        String str;
        while ((str = br.readLine()) != null){
            System.out.println(str);
        }
        //釋放資源
        br.close();
    }
}

序列化和反序列化

  • 對象流指的是能夠直接把一個對象以流的形式傳輸給其餘的介質,好比硬盤。

  • 一個對象以流的形式寫入文件進行保存,叫作序列化

  • 把文件保存的對象以流的形式讀取出來,叫作反序列化

  • 該對象所對應的類,必須實現Serializable接口

    Serializable接口也叫標記型接口,要進行序列化和反序列化的類必須實現Serializable接口,給該類添加一個標記,當進行序列化和反序列化時,就會檢測類上是否有這個標記。有標記就能夠序列化和反序列化,沒有就會拋出NotSerializableException異常

  • 被static(靜態關鍵字)和transient(瞬態關鍵字)修飾的成員變量不能被序列化

import java.io.Serializable;

public class Person implements Serializable {
    //自定義一個序列版本號,
    // 添加新的屬性時從新編譯,能夠直接反序列化,不會拋出異常
    //該序列號即爲默認的序列號
    static final long serialVersionUID  = 2L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

//序列化
public class ObjectOutputStream01 {
    public static void main(String[] args) throws IOException {
        //建立ObjectOutputStream對象,構造方法中傳遞字節輸出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
        //利用writeObject方法寫入Person對象
        oos.writeObject(new Person("angel", 18));
        //釋放資源
        oos.close();
    }
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

//反序列化
public class ObjectInputStream01 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //建立ObjectInputStream對象,構造方法傳入字節輸入流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
        //使用readObject方法讀取保存對象的文件
        Object o = ois.readObject();
        //釋放資源
        ois.close();
        System.out.println(o.toString());
    }
}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息