天天看點

Java IO學習筆記(一) —— IO基礎Java IO學習筆記(一) —— IO基礎

Java IO學習筆記(一) —— IO基礎

Java IO 流學習筆記

1 什麼是流

記憶體與儲存設備之間傳輸資料的通道。

2 流的分類

2.1 按方向

  • 輸入流:将儲存設備中的内容讀取到記憶體中;
  • 輸出流:将記憶體中的内容寫入到儲存設備中。

2.2 按機關

  • 位元組流:以位元組為機關,可以讀取所有資料;
  • 字元流:以字元為機關,隻能讀取文本資料。

位元組(Byte)是計量機關,表示資料量多少,是計算機資訊技術用于計量存儲容量的一種計量機關,通常情況下一位元組等于八位。

字元(Character)計算機中使用的字母、數字、字和符号,比如’A’、‘B’、’$’、’&'等。

2.3 按功能

  • 節點流:具有實際傳輸資料的讀寫功能;
  • 過濾流:在節點流的基礎之上增強的功能。

3 位元組流抽象類

  • InputStream

    這個抽象類是表示輸入位元組流的所有類的超類。

    需要定義InputStream子類的應用InputStream必須始終提供一種傳回輸入的下一個位元組的方法。

  • OutputStream

    這個抽象類是表示位元組輸出流的所有類的超類。 輸出流接收輸出位元組并将其發送到某個接收器。

    需要定義OutputStream子類的應用OutputStream必須至少提供一個寫入一個位元組輸出的方法。

4.檔案輸入輸出流

4.1 FileInputStream輸入流

(1) read() 單位元組讀取

/**
     * 單位元組讀取
     * read(): 從該輸入流讀取下一個資料位元組
     * @param filePath
     */
    public static void demo1(String filePath){
        try(FileInputStream fileInputStream = new FileInputStream(filePath)){
            int data;
            while ((data = fileInputStream.read()) != -1){
                System.out.print((char) data);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
           

(2)read(byte[] b) 一次讀取多個位元組

/**
     * 一次讀取多個位元組
     *
     * read(byte[] b):從該輸入流讀取最多 byte.length個位元組的資料到位元組數組。
     * @param filePath
     */
    public static void demo2(String filePath){
        try(FileInputStream fileInputStream = new FileInputStream(filePath)){
            byte[] buf = new byte[3]; // 大小為3的緩存區
            int count = 0;
            while((count = fileInputStream.read(buf)) != -1){
                System.out.println(new String(buf, 0, count));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
           

(3) read(byte[] b, int off, int len)

/**
     *一次讀取多個位元組
     *
     * read(byte[] b, int off, int len)
     * 從該輸入流讀取最多 len位元組的資料到位元組數組。
     * @param filePath
     */
    public static void demo3(String filePath){
        try(FileInputStream fileInputStream = new FileInputStream(filePath)){
            byte[] buf = new byte[3]; // 大小為3的緩存區
            int count = 0;
            while((count = fileInputStream.read(buf,0,buf.length)) != -1){
                System.out.println(new String(buf, 0, count));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
           

4.2 FileOutputStream檔案輸出流

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        String filePath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
        try(FileOutputStream out = new FileOutputStream(filePath)){
            out.write("hello word!".getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

4.3 檔案輸入輸出流案例

public class FileCopyDemo {
    public static void main(String[] args) {
        // 1.建立流,檔案輸入流,檔案輸出流
        String orgPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
        String tarPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ddd.txt";

        try (
                FileInputStream in = new FileInputStream(orgPath);
                FileOutputStream out = new FileOutputStream(tarPath);
        ) {
       // 2 邊讀邊寫
            byte[] buf = new byte[1024];
            int count = 0;
            while ((count = in.read(buf)) != -1) {
                out.write(buf, 0, count);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

5 位元組緩沖流

緩沖流:BufferedInputStream/ BufferedOutputStream

  • 提高IO效率,減少通路磁盤次數
  • 資料存儲在緩沖區中,flush是将緩沖區的内容寫入檔案中,也可以直接close

5.1 BufferedInputStream

public class BufferedInputStreamDemo {

    public static void main(String[] args) {
        String filePath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
        try (
                FileInputStream fis = new FileInputStream(filePath);
                BufferedInputStream bis = new BufferedInputStream(fis)
        ) {
            // 2 讀取
            int data = 0;
            while ((data = bis.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

5.2 BufferedOutputStream

public class BufferedOutputStreamDemo {
    public static void main(String[] args) {
        String tarPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/eee.txt";
        try (
                FileOutputStream fos = new FileOutputStream(tarPath);
                BufferedOutputStream bos = new BufferedOutputStream(fos)
        ) {
            // 寫入檔案
            for (int i = 0; i < 10; i++) {
                bos.write("hello".getBytes());// 寫入8k緩沖區
                bos.flush(); // 重新整理到硬碟
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

6 對象流

ObjectOutputStream / ObjectInputStream

  • 增強了緩沖區功能
  • 增強了讀寫8種基本資料類型和字元串的功能
  • 增強了讀寫對象的功能

    readObject() 從流中讀取一個對象

    writeObject(Object obj) 向流中寫入一個對象

    使用流傳輸對象的過程稱為序列化、反序列化

6.1 使用ObjectOutputStream實作對象的序列化

public class ObjectOutputStreamDemo {

    public static void main(String[] args) {
        // 1.建立對象流
        try (
                FileOutputStream fos = new FileOutputStream("/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/student.bin");
                ObjectOutputStream oos = new ObjectOutputStream(fos)
        ) {
            // 2.序列化
            Student student = new Student();
            student.setAge(14);
            student.setName("hello");

            oos.writeObject(student);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

6.2 使用ObjectInputStream實作對象的反序列化

public class ObjectInputStreamDemo {
    public static void main(String[] args) {
        try (
                FileInputStream fis = new FileInputStream("/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/student.bin");
                ObjectInputStream ois = new ObjectInputStream(fis);
        ) {
            Student stu = (Student) ois.readObject();
            System.out.println(stu.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
           

6.3 注意事項

  • 1.某個類要想序列化必須實作Serializable接口
  • 2.序列化類中對象屬性要求實作Serializable接口
  • 3.序列化版本号ID,保證序列化的類和反序列化的類是同一個類
  • 4.使用transient修飾屬性,這個屬性就不能序列化
  • 5.靜态屬性不能序列化
  • 6.序列化多個對象,可以借助集合來實作