【JAVA】筆記(18)--- IO流 精講


FileInputStream-FileOutputStream:


1.構造方法:

new ( "文件的 絕對路徑/相對路徑" ) ;

//注意構造方法的參數是字符串類型

//絕對路徑為帶磁盤目錄的,如:C:\java-prictice\javaseplus\text

//相對路徑:(IDEA默認當前路徑:當前模塊的根)+相對路徑

//通過“電腦”復制文件位置的時候,要在上邊的那個路徑的后面+ “\具體文件名”,否則此路徑只是代表你看到界面的上一個目錄;

//把路徑粘貼到構造方法里的時候,IDEA工具會自動把“ \ ”轉換為“ \\ ”,實際上,把“ \\ ”改為“ / ”也是正確的;

FileInputStream 引用文件,代表將此文件作為讀的對象;

FileOutputStream 引用文件,代表將此文件作為寫的對象(輸出在此文件中),若此文件不存在,則會自動創建;

2.常用方法:

1)FileInputStream . read ( bytes數組 ) //讀取流的字節,並將讀取的字節放到byte數組里,返回讀取字節個數(int)[ 若讀到文件末尾,則返回-1 ]

2)FileInputStream . available ( int ) //返回流當前未讀取的字節個數

3)FileInputStream . skip ( int )  //跳過幾個字節不讀

3.注意:

1)為方便 finally語句中對流的關閉,所以一般在try外邊聲明空指針引用,在try里邊new流對象;

2)聲明的byte數組長度不宜過長,因為內存中很難找到一條特別長的連續空間;

3)每個流不能一起(並列)關閉,避免出現異常導致有些流無法關閉;

4.拷貝文件:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//File字節流拷貝
public class FileInputStreamTest {
    public static void main(String[] args) {
        //聲明 FileInputStream 引用為空
        FileInputStream fis=null;
        //聲明 FileOutputStream 引用為空
        FileOutputStream fos=null;
        //拷貝的重要操作(拋出異常的部分)放到try-catch里
        try {
            //創建文件字節輸入流
            fis=new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt");
            //創建文件字節輸出流
            fos=new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugFISCopy.txt",true);
            //創建長度為100的數組bytes,元素類型為byte(字節)
            byte [] bytes=new byte[100];
            //聲明“讀取字節個數”的變量
            int readCount;
            //讀取fis的“bytes.length”個字節,同時判斷是否退出循環
            //循環退出條件:讀取字節個數為 -1
            while ((readCount=fis.read(bytes))!=-1){
                //將此時bytes里裝的字節寫入fos對象里
                fos.write(bytes,0,readCount);
            }
            //刷新輸出流
            fos.flush();
        } catch (FileNotFoundException e) {//用IDEA工具生成
            e.printStackTrace();
        } catch (IOException e) {//用IDEA工具生成
            e.printStackTrace();
        } finally {//fis與fos分開關閉,避免彼此的影響
            if (fis!=null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
 

 

FileReader-FileWriter:


1.構造方法:

FileReader  構造方法參考 《FileInputStream-FileOutputStream》

FileWriter   構造方法:

//此流的writer方法,會將寫的字符覆蓋整個文本(原文件中的字符會被刪除,然后錄入寫的字符)
FileWriter fileWriter1=new FileWriter("C:\\Program Files\\Git\\bin");
//此流的writer方法,會將寫的字符添加到文本后面(原文件中的字符不變)
FileWriter fileWriter2=new FileWriter("C:\\Program Files\\Git\\bin",true);

2.常用方法:

參照 《FileInputStream-FileOutputStream》與下面的《拷貝文件》;

3.注意:

字節流拷貝文件時,數組聲明為byte類型,那用字符流時,自然就聲明為char類型;

字符流綁定的文件格式只能是“ . txt ” 格式;

4.拷貝文件:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//File字符流拷貝
public class FileWriteTest {
    public static void main(String[] args) {
        FileReader in=null;
        FileWriter out=null;
        try {
            in=new FileReader("C:\\java-prictice\\javaseplus\\pra\\debug.txt");
            out=new FileWriter("C:\\java-prictice\\javaseplus\\pra\\debugFWCopy.txt",true);
            char [] chars=new char[3];
            int readCount;
            while ((readCount=in.read(chars))!=-1){
                out.write(chars,0,readCount);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (in!=null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out!=null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

BufferedReader-BufferedWriter:


1.BufferedReader,BufferedWriter,都是自帶緩沖的流,換句話說,不需要提供數組,也可以拷貝文本;

2.構造方法:

BufferedReader 參數:字符輸入流(FileRead)

BufferedWriter  參數:字符輸出流(FileWriter)

InputStreamReader 參數:字節輸入流(FileInputStream)//將字節輸入流轉換為字符輸出流

OutputStreamWriter 參數:字節輸出流(FileOutputStream)//將字節輸出流轉換為字符輸出流

綜上,可以這么寫:

BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt")));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true)));

3.常用方法:

BufferedReader . readLine ( ) //讀取流當前行

BufferedWriter . write ( ) //寫入流當前行

4.拷貝文件代碼:

import java.io.*;
//Buffered字符流拷貝
public class BufferedReadTest {
    public static void main(String[] args) {
        BufferedReader br=null;
        BufferedWriter bw=null;
        try {
            br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt")));
            bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true)));
            String read;
            while ((read=br.readLine())!=null){
                bw.write(read);
              	//讓文本一行一行的寫出來
                bw.write("\n");
            }
            bw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

 

DataOutputStream-DataInputStream:


1.DataOutputStream,DataInputStream 都是數據專屬流,這個流可以將數據連同數據的類型一並寫入文件;

2.注意:

DataOutputStream 寫的文件,只能用 DataInputStream 去讀,並且讀的時候,讀的順序必須和寫的順序一樣,才可以正常取出數據;

專屬流讀和寫的文件都不是普通文檔(用記事本看不到正常信息);

3.“讀寫”訓練:

import java.io.*;
public class DataOutputStreamTest {
    public static void main(String[] args) {
        DataOutputStream dos=null;
        DataInputStream dis=null;
        try {
            dos=new DataOutputStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt",true));
            dis=new DataInputStream(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt"));
            byte b=100;
            short s=200;
            int i=300;
            long l=400l;
            float f=500.0f;
            double d=600.0;
            boolean sex=true;
            char c='c';
            dos.writeByte(b);
            dos.writeShort(s);
            dos.writeInt(i);
            dos.writeLong(l);
            dos.writeFloat(f);
            dos.writeDouble(d);
            dos.writeBoolean(sex);
            dos.writeChar(c);
            dos.flush();
            System.out.println(dis.readByte());
            System.out.println(dis.readShort());
            System.out.println(dis.readInt());
            System.out.println(dis.readLong());
            System.out.println(dis.readFloat());
            System.out.println(dis.readDouble());
            System.out.println(dis.readBoolean());
            System.out.println(dis.readChar());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dis!=null){
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dos!=null){
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
點擊查看輸出結果
100
200
300
400
500.0
600.0
true
c

Process finished with exit code 0

 

PrintStream:


1.PrintStream 屬於標准字節輸出流,默認輸出到控制台上;

2.舉個栗子:

import java.io.PrintStream;
public class pra{
    public static void main(String[] args) {
        PrintStream ps=System.out;
        ps.println("輸出到控制台上");
    }
}

運行結果:
------------------------
輸出到控制台上

Process finished with exit code 0

3.改變 PrintStream 的輸出方向:

  import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PrintStreamTest {
    public static void main(String[] args) {
        //向日志中導入msg字符串
        Logger.log("調用了 System 的 gc() ,建議啟動垃圾回收器");
        Logger.log("調用了 UserSystem 的 book()");
        Logger.log("用戶嘗試登錄,驗證失敗");
    }
}
//日志類
class Logger {
    public static void log(String msg) {//獲取字符串msg
        //聲明空引用
        PrintStream printStream=null;
        try {
            //printStream流 綁定此文件
            printStream = new PrintStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\log.txt",true));
            //改變System.out的輸出方向(輸出的東西會進入printStream流)
            System.setOut(printStream);
            //獲取此時刻時間
            Date nowTime =new Date();
            //自定義時間格式
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            //將nowTime轉換為我們的自定義格式,然后將msg字符串拼接上,最后輸出
            System.out.println(sdf.format(nowTime)+" : "+msg);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

4.注意:標准輸出流不需要手動 clsoe 流;

 

File 類:


1.概述:File 類與IO流四大家族無繼承關系,所以File類不能完成文件的讀與寫;

2.構造方法:new ( " 路徑 " ) ;

3.常用方法:

引用 . createNewFile ( ) //在指定位置創建一個空文件(成功就返回true,如果已存在就不創建,然后返回false)

引用 . mkdir ( ) // 在指定位置創建一個文件夾

引用 . mkdirs ( ) // 在指定位置創建一個多重文件夾

 

引用 . exists ( ) // 判斷文件或文件夾是否存在

引用 . isFile ( ) // 判斷是否是一個文件,返回 boolean

引用 . isDirectory ( ) // 判斷是否是一個目錄,返回 boolean

 

引用 . getAbsolutePath ( ) // 獲取文件的絕對路徑,與文件是否存在沒關系

引用 . getParent ( ) // 返回此文件路徑的父路徑(String),如果此路徑名沒有指定父目錄,則返回null

引用 . getName ( ) //  獲取文件或文件夾的名稱,不包含上級路徑

引用 . length ( ) // 返回此文件大小(字節)

引用 . lastModified ( ) // 獲取文件最后一次被修改的時間

引用 . listFiles ( ) // 返回當前目錄下的所有子文件(返回值類型為 FIle數組) 

 

序列化 / 反序列化:


1.概述:

2.自定義的類需要實現 Serializable 接口,才支持序列化和反序列化;

3.序列化版本號:

實現了 Serializable 接口的類,系統會為其自動生成一個序列化版本號,但是最好咱們手動生成版本號舉個栗子:

import java.io.Serializable;
class Car implements Serializable{
    private static final long serialVersionUID = 8342087006090942735L;
}

java虛擬機識別一個類,首先看類名,其次看序列化版本號;

4.被 transient 關鍵字修飾的屬性不參與序列化:

private transient String name;

 

ObjectInputStream-ObjectOutputStream:


此體系知識請參考《上邊的》

結合栗子理解:

  import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ObjectInputStreamTest {
    public static void main(String[] args) throws Exception{//將所有異常拋出
        //ObjectOutputStream 綁定Cars文件(若無則新建)
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Cars"));
        //ObjectInputStream 綁定已存在的Cars文件
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Cars"));
        //創建專門裝Car的集合cars
        List<Car> cars=new ArrayList<>();
        //向cars集合中添加元素
        cars.add(new Car(1,"大眾"));
        cars.add(new Car(2,"法拉利"));
        cars.add(new Car(3,"豐田"));
        //將集合cars寫入oos綁定文件中(反序列化)
        oos.writeObject(cars);
        //讀取ois綁定文件中的所有對象(序列化),並強轉為List<Car>類型,最后將所有對象裝到carsList集合中
        List<Car> carsList= (List<Car>) ois.readObject();
        //遍歷carsList集合
        for (Car car:carsList) {
            System.out.println(car);
        }
        oos.flush();
        oos.close();
        ois.close();
    }
}
class Car implements Serializable{
    private static final long serialVersionUID = -2630683108946058933L;
    private int no;
    private String brand;
    public Car() {
    }
    public Car(int no, String model) {
        this.no = no;
        this.brand = model;
    }
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public String getModel() {
        return brand;
    }
    public void setModel(String model) {
        this.brand = model;
    }
    @Override
    public String toString() {
        return "Car{" +
                "no=" + no +
                ", model='" + brand + '\'' +
                '}';
    }
}

控制台輸出結果:
---------------------------
Car{no=1, model='大眾'}
Car{no=2, model='法拉利'}
Car{no=3, model='豐田'}

Process finished with exit code 0

 

IO+Properties:


1.優點:

對於以后需要經常改變的數據,可以單獨寫到一個文件中,使用程序動態讀取;將來只需要修改這個文件的內容, java代碼不需要改動,不需要重新編譯,服務器也不需要重啟,就可以拿到動態的信息;類似這種機制的這種文件被稱為配置文件;

2.當配置文件中的內容格式為:

key1=value 

key2=value

我們把這種配置文件叫做屬性配置文件

3.注意:

java 規范中有要求:屬性配置文件建議以 “ . properties ”結尾;這種以 ”. properties “結尾的文件在java中被稱為:屬性配置文件;

Properties 是專門存放屬性配置文件內容的一個類;

4.栗子老師:

import java.io.FileReader;
import java.util.Properties;
public class IOProperties {
    public static void main(String[] args) throws Exception{
        //FileReader綁定文件
        FileReader reader=new FileReader("C:\\java-prictice\\javaseplus\\pra\\IOPropertiesTest.txt");
        Properties pro=new Properties();
        //將FileReader綁定文件載入Pro集合
        pro.load(reader);
        //通過key獲取value
        System.out.println(pro.getProperty("username"));
        System.out.println(pro.getProperty("password"));
        System.out.println(pro.getProperty("data"));
        System.out.println(pro.getProperty("不存在的key,會輸出 null"));
    }
}

運行結果:
-----------------------------
a01
123456a01
null
null

Process finished with exit code 0

 

隨筆:


節點流:本身作為包裝流的構造方法的參數;

包裝流:包裝流的構造方法的參數是節點流;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM