天天看點

03-Java核心類庫_IO三,IO

目錄

三,IO

1,java.io.File

1.1 常用構造方法

1.2 其他常用方法

1.3 字段

2,檔案周遊案例

3,檔案過濾器

應用執行個體

改進

4,相對與絕對路徑

5,流概述

6,java.io.OutputStream

7,java.io.FileOutputStream

8,java.io.FileInputStream

8.1 常用方法

8.2 常見子類——FileInputStream

9,檔案加密和解密工具

10,位元組流讀取文字

11,字元輸出

12,字元讀取

13,flush重新整理管道

14,位元組轉換字元流

15,Print與BufferedReader

15.1 列印流

15.2 緩存讀取流

16,收集異常日志

17,properties

17.1 概述

17.2 常用方法

18,序列化技術

18.1 概述

18.2 序列化

18.3 反序列化

19,try-with-resources

19.1 原因

19.2 解決方法

三,IO

1,java.io.File

1.1 常用構造方法

1,構造方法聲明

03-Java核心類庫_IO三,IO

2,File​(String pathname)

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

3,File​(File parent, String child)

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

4,File​(String parent, String child)

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

1.2 其他常用方法

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

1.3 字段

不同作業系統路徑分隔符可能不同,"//"不會适用于所有作業系統

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

2,檔案周遊案例

package zuoye;

import java.io.File;


public class Demo4 {
    public static void main(String[] args) {
        File e = new File("e://");
        File[] files = e.listFiles();    // 獲得E盤下所有檔案
        listFile(files);                 // 調用周遊的方法

    }

    public static void listFile(File[] files){
        if(files!=null&&files.length>0){ // 檔案存在且不為空
            for (File file:files) {
                if(file.isFile()){       // 是檔案
                    if(file.getName().endsWith(".avi")){    // 選擇avi字尾的
                        if(file.length()>100*1024*1024)     // 檔案大小大于100M
                        System.out.println("找到了一個avi檔案"+file.getAbsolutePath());
                    }
                }else {                  // 是檔案夾
                    File[] files2 = file.listFiles();
                    listFile(files2);    // 遞歸
                }
            }
        }

    }
}


           

3,檔案過濾器

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

應用執行個體

package com.kaikeba;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File e = new File("d://");
        listFiles(e);
    }
    public static void listFiles(File file){    // 自定義的方法
        if(file != null && file.length() != 0){ // 檔案存在且不為空
            // 1,建立一個過濾器,并描述規則
            FileFilter filter = new AVIFileFilter();
            // 2,通過檔案擷取子檔案夾
            File [] files = file.listFiles(filter); // 對象的方法
            // 3,遞歸周遊所有檔案
            for(File f : files) {
                if(f.isDirectory()) {
                    listFiles(f);
                }else {
                    System.out.println("發現一個txt檔案:" + f.getAbsolutePath());
                }
            }
        }
    }
    static class AVIFileFilter implements FileFilter{    // 為實作過濾器接口 需要定義一個類 這裡為靜态内部類
        @Override
        public boolean accept(File pathname) {
            // 隻保留txt檔案和檔案夾
            if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
                return true;
            }
            return false;
        }
    }
}
           

改進

用匿名内部類實作FileFilter接口,并直接作為參數,調用listFiles獲得篩選過後的檔案
package com.kaikeba;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File e = new File("d://");
        listFiles(e);
    }
    public static void listFiles(File file){
        if(file != null && file.length() != 0){ // 檔案存在且不為空
            File [] files = file.listFiles(new FileFilter() {   // 通過匿名内部類作為參數的方法 實作過濾
                @Override
                public boolean accept(File pathname) {
                    // 隻保留txt檔案和檔案夾
                    if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
                        return true;
                    }
                    return false;
                }
            });
            // 遞歸周遊所有檔案
            for(File f : files) {
                if(f.isDirectory()) {
                    listFiles(f);
                }else {
                    System.out.println("發現一個txt檔案:" + f.getAbsolutePath());
                }
            }
        }
    }
}
           

4,相對與絕對路徑

絕對路徑:以盤符開始,是一個完整的路徑,例如c://a.txt

相對路徑:java中是相對于項目目錄路徑,這是一個不完整的路徑,在Java開發中很常用    例如  a.txt

03-Java核心類庫_IO三,IO

5,流概述

package com.java.demo;


import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @author liweijie
 */
public class Demo {
    /**
     * IO流概述
     *  可以将這種資料傳輸操作,看做一種資料的流動 , 按照流動的方向分為輸入Input和輸出Output
     *  Java中的IO操作主要指的是 java.io包下的一些常用類的使用. 通過這些常用類對資料進行讀取(輸入Input) 和 寫出(輸出Output)
     *
     * IO流的分類:
     *  按照流的方向來分,可以分為:輸入流和輸出流.
     *  按照流動的資料類型來分,可以分為:位元組流和字元流
     *
     *     位元組流:(頂級父類)
     *          -   輸入流 :   InputStream
     *          -   輸出流 :   OutputStream
     *     字元流:(頂級父類)
     *          -   輸入流 :   Reader
     *          -   輸出流 :   Writer
     *
     *
     * 一切皆位元組:
     *      計算機中的任何資料(文本,圖檔,視訊,音樂等等)都是以二進制的形式存儲的.
     *      在資料傳輸時 也都是以二進制的形式存儲的.
     *      後續學習的任何流 , 在傳輸時底層都是二進制.
     * @param args
     */
    public static void main(String[] args) throws FileNotFoundException {


    }

}
           

6,java.io.OutputStream

     *      一切皆位元組:

     *      計算機中的任何資料(文本,圖檔,視訊,音樂等等)都是以二進制的形式存儲的.

     *      在資料傳輸時 也都是以二進制的形式存儲的.

     *      後續學習的任何流 , 在傳輸時底層都是二進制.

OutputStream是抽象類

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

注意:

寫完一定要關閉close;

03-Java核心類庫_IO三,IO

7,java.io.FileOutputStream

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
其中append為true則表示,在檔案末尾添加資料,否則表示重新寫入資料
package zuoye;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class Demo6 {
    public static void main(String[] args) throws IOException {
        //OutputStream
        FileOutputStream fos = new FileOutputStream("c://a.txt"); // 沒有添加append參數,表示預設false 即覆寫原資料
        byte[] bytes = {65,66,67,68,69};
        fos.write(bytes);
        fos.close();                //寫在哪在哪關閉
        System.out.println("已經寫出");

    }
}
           
通過字元串+getBytes函數,獲得位元組數組:
03-Java核心類庫_IO三,IO

8,java.io.FileInputStream

8.1 常用方法

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

8.2 常見子類——FileInputStream

1)構造方法

03-Java核心類庫_IO三,IO

2)read()方法

03-Java核心類庫_IO三,IO

3)read​(byte[] b)

注:代碼中漏掉了fis.close(),這種錯誤一定要避免!!!

03-Java核心類庫_IO三,IO

改進方法(記錄讀取到的位元組數)

03-Java核心類庫_IO三,IO

9,檔案加密和解密工具

示例代碼

package com.kaikeba;

import java.io.*;
import java.util.Scanner;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("請輸入檔案路徑名:");
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        File oldFile = new File(s);
        File newFile = new File(oldFile.getParent() + "_new_File_" + oldFile.getName());
        FileInputStream fis = new FileInputStream(oldFile);
        FileOutputStream fos = new FileOutputStream(newFile);
        while (true) {
            byte b = (byte) fis.read();
            if(b == -1) {
                break;
            }
            fos.write(b ^ 10);// 加密(一個數異或兩次,還是本身)
        }
        fis.close();
        fos.close();
        System.out.println("加密/解密結束");
    }

}
           

加密(新檔案的命名方式修改了,但截圖中并沒有糾正過來)

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

再次運作程式進行解密(正确修改)

03-Java核心類庫_IO三,IO

10,位元組流讀取文字

由于工程使用的是UTF-8字元編碼,是以在讀取工程中的文本檔案時,不會出現亂碼

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

由于提前限定了一次讀取的位元組數為10,是以出現了讀取不到一個完整漢字的情況,因而出現亂碼。但是UTF-8使用動态編碼表,由于提前不知道每個字元需要多少位元組,是以此方法不行。

是以下面引入了字元流,用來解決讀取半字的問題

11,字元輸出

字元流用來操作文字,而位元組流可以操作任何檔案,是以位元組流更加常用。

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

注意:

決定是否在原檔案基礎上追加的,是聲明字元流對象是的append屬性(為true則是追加模式);

append與write在實際實作上,沒有差別,但是append會傳回Writer對象;

03-Java核心類庫_IO三,IO
append方法的傳回值(Writer類型)可以強轉為該對象(FileWriter類型),是以可以繼續調用append,因而稱為“追加”;
03-Java核心類庫_IO三,IO

12,字元讀取

基本使用方法同位元組流。

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

13,flush重新整理管道

字元輸出時,以字元為機關,但計算機中都是以位元組為機關。當一個字元占用多個位元組時,字元輸入流未讀取單個字元全部位元組之前,會将已讀取位元組放入緩存;

字元輸出流fw.flush()會将緩存中字元強制寫入到檔案中,fw.close()也會有此效果;

如果不執行的話,就不會将字元寫入檔案中,如圖:

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

14,位元組轉換字元流

轉換流。将位元組流裝飾為字元流:使用了裝飾者模式;

為什麼要使用位元組流+轉換流?直接字元流不香嗎?:由于平常使用時,可能擷取的是位元組流,是以才有這種轉換方式

03-Java核心類庫_IO三,IO

15,Print與BufferedReader

15.1 列印流

1)列印位元組流與列印字元流

列印位元組流

03-Java核心類庫_IO三,IO

列印字元流(記得flush或close)

03-Java核心類庫_IO三,IO

列印位元組流和列印字元流在使用上差别不大,但字元流需要調用flush,否則不會寫入到檔案中;

2)位元組流轉換為列印流

03-Java核心類庫_IO三,IO

15.2 緩存讀取流

将字元輸入流轉換為帶有緩存可以一次讀取一行的緩存字元讀取流

位元組流-》字元流-》緩存讀取流

03-Java核心類庫_IO三,IO

當讀取到末尾時,會傳回null

16,收集異常日志

普通的異常控制台顯示

03-Java核心類庫_IO三,IO

可以将異常資訊儲存在txt文檔中,并加上日期,便于後期核查

03-Java核心類庫_IO三,IO

17,properties

17.1 概述

03-Java核心類庫_IO三,IO

properties繼承HashTable屬于Map集合(鍵值對),但其擴充部分含有IO相關用法(配置檔案)

17.2 常用方法

1)store方法:将properties對象内容寫入位元組流/字元流所指的檔案中

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

2)load方法:将位元組流/字元流指向的檔案内容加載到properties對象中

03-Java核心類庫_IO三,IO
03-Java核心類庫_IO三,IO

3)get與getProperty

03-Java核心類庫_IO三,IO

get傳回Object對象,getProperty傳回字元串。

03-Java核心類庫_IO三,IO

18,序列化技術

18.1 概述

由于垃圾回收機制的存在,一些屬性或對象,在程式關閉之後,便消失,無法重複利用,是以有人在想能不能将把對象完整的存儲在檔案中,使用時再取出來,即對象在記憶體中存儲的字元序列(看上去像是亂碼);

将檔案中的對象讀取到程式中來,就是反序列化;

雖然序列化很友善,但是卻十分容易産生Bug(占Bug總數将近三分之一),是以Java官方提出近幾年将要進行整改,建議大家不要使用此方法;(了解下也是有必要的)

18.2 序列化

Java官方規定,所有對象均不能序列化,想要序列化,需添加标記

03-Java核心類庫_IO三,IO

添加标記:實作接口Serializable。添加代碼後沒有任何飄紅,即說明不需要實作任何方法,是以這個接口被稱為标記接口。

03-Java核心類庫_IO三,IO

18.3 反序列化

03-Java核心類庫_IO三,IO

19,try-with-resources

19.1 原因

1)在檔案流使用完畢後需要關閉

03-Java核心類庫_IO三,IO

2)為了使close一定被執行,需要将其放在finally中

03-Java核心類庫_IO三,IO

3)是以需要将fr提到try之前,但仍可能産生空指針異常

03-Java核心類庫_IO三,IO

4)繼續try-catch處理

03-Java核心類庫_IO三,IO

5)綜上,這麼多步驟就是為了讀入一個字元

19.2 解決方法

1)jdk1.7之前:在try中new的對象會在try或catch塊執行完畢後執行close。但要求,能使用此方法的類必須實作Closeable或AutoCloseable兩個接口

03-Java核心類庫_IO三,IO

2)但是,如果後面還有代碼塊需要用到try中的對象時,就顯得不友善了。JDK9進行了改進

03-Java核心類庫_IO三,IO

繼續閱讀