IO流

問題背景

如果我們要存數(shù)據(jù),我們可以存在數(shù)組里集合里,但是他們都有一個(gè)共性,那就是存在內(nèi)存當(dāng)中。優(yōu)點(diǎn)就是我們讀取的比較快。缺點(diǎn)就是當(dāng)我們重新啟動(dòng)項(xiàng)目的時(shí)候,這些數(shù)據(jù)就會(huì)消失。 為了對數(shù)據(jù)進(jìn)行持久化的保存,就可以把數(shù)據(jù)存在文件當(dāng)中,為了解決這個(gè),java為我們提供了IO流。

流(數(shù)據(jù)流動(dòng))

數(shù)據(jù)流動(dòng)的方向分為

  • 讀數(shù)據(jù)(輸入Input)
  • 寫數(shù)據(jù)(輸出Output)

什么叫文件

一種電腦的存儲形式

File是一個(gè)java.io包中的類

File是在內(nèi)存中的一個(gè)對象<---映射--->硬盤上的文件或文件夾

路徑是看創(chuàng)建的對象能否與硬盤中的一個(gè)真實(shí)的文件產(chǎn)生對應(yīng)映射關(guān)系,編譯不會(huì)報(bào)錯(cuò),只有當(dāng)通過文件流去讀取文件的內(nèi)容時(shí)才會(huì)報(bào)錯(cuò)。

系統(tǒng)內(nèi)硬盤上文件的名字是不區(qū)分大小寫的。

File類常用API

File file = new File("D:"+ File.separator + "testFile.txt");
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isDirectory());
System.out.println(file.isHidden());
System.out.println(file.isFile());

什么是文件流

顧名思義 讀取文件的信息(in) 將信息寫入文件中(out)

按照讀取或?qū)懭氲膯挝唬ㄗ止?jié)數(shù))大小來區(qū)分

字節(jié)型文件流(1字節(jié))

? FileInputStream/FileOutputStream

字符型文件流(2字節(jié)--1字符)

? FileReader/FileWriter

/*
測試FileInputStream
read():從管道一個(gè)字節(jié)一個(gè)字節(jié)的讀,返回值是Unicode碼,其中要注意的是\r\n的字節(jié)碼是13和10
read(byte[] b):每次從流管道中讀取若干個(gè)字節(jié),存入數(shù)組中,返回值為有效元素個(gè)數(shù)
available():返回值顯示流管道中緩存的字節(jié)數(shù)
skip(long n):跳過幾個(gè)字節(jié),再讀取(多線程讀文件可以利用)
*/
FileInputStream fileInputStream = null;
try {
    File file = new File("D:" + File.separator + "testFile.txt");
    fileInputStream = new FileInputStream(file);
    int available = fileInputStream.available();//顯示流管道中有多少緩存字節(jié)
    System.out.println(available);
    byte[] b = new byte[5];
    int read = fileInputStream.read(b);
    while (read != -1) {
        String string = new String(b, 0, read);
        System.out.println(string);
        read = fileInputStream.read(b);
    }
    /*int i = fileInputStream.read();//讀不到則返回值為-1
            while (i != -1) {
                System.out.println(i);
                i = fileInputStream.read();
            }*/
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}  finally {
    try {
        if (fileInputStream != null) {
            //將流通道關(guān)閉
            fileInputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
/**
測試FileOutputStream
將String轉(zhuǎn)成byte,調(diào)用getBytes()方法
*/
FileOutputStream fos = null;
try {
    fos = new FileOutputStream(new File("D:" + File.separator + "lili.txt"), true);
    String str = "dgergdfgdfgdfg";
    byte[] bytes = str.getBytes();
    fos.write(bytes);
    //fos.write(97);//將b寫入到管道中
    fos.flush();//刷新,將管道中的字節(jié)推送到File中
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (fos != null) {
            fos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
/*
文件的復(fù)制
*/
public void copyFile(File file, String path) {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        fis = new FileInputStream(file);
        fos = new FileOutputStream(new File(path + File.separator + file.getName()));
        byte[] b = new byte[1024];
        int read = fis.read(b);
        while (read != -1) {
            fos.write(b, 0, read);//將文件的有效字節(jié)寫入
            fos.flush();
            read = fis.read(b);
        }
        System.out.println("復(fù)制完成");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String[] args) {
    new OperationFile().copyFile(new File("D:" + File.separator + "lili.txt"), "G:");
}

/*
加強(qiáng)版
*/
public void copyPlusFile(File file, String newPath) {

    //獲取當(dāng)前File的絕對路徑,用拼串的方式獲取新的路徑的名字
    String oldFilePath = file.getAbsolutePath();
    String newFilePath = newPath + oldFilePath.split(":")[1];
    //創(chuàng)建一個(gè)新的文件夾
    File newFile = new File(newFilePath);
    File[] files = file.listFiles();
    if (files != null) {//是一個(gè)文件夾
        newFile.mkdir();
        if (files.length != 0) {
            for (File file1 : files) {
                this.copyFile(file1, newPath);
            }
        }
    } else {//是一個(gè)文件
        //讀取舊的文件和寫入新的文件
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(oldFilePath);
            fos = new FileOutputStream(newFilePath);
            byte[] b = new byte[1024];
            int count = fis.read(b);//讀取的有效字節(jié)
            while (count != -1) {
                fos.write(b, 0, count);
                fos.flush();//將流管道元素清空出去
                fis.read(b);
            }
            System.out.println(newFile.getName() + "文件復(fù)制完畢");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字符型文件流

只能操作純文本文件(文件右鍵,記事本能打開)

//read(char[] c)
FileWriter fr = new FileReader(file);
String srt = "abc";
char[] c = srt.toCharArray();
FileWriter fw = new FileWriter(file);
fw.write(c);
fw.write(srt);

存儲信息的方式(為什么要操作File)

  1. 變量 只能存一份

  2. 數(shù)組 存儲好多個(gè) 數(shù)據(jù)類型統(tǒng)一

  3. 集合 存儲好多個(gè) 存儲后個(gè)數(shù)還能改變 泛型----數(shù)據(jù)類型統(tǒng)一

    以上三個(gè)都是Java中的類型==(對象存儲在內(nèi)存中)==

    都存儲在內(nèi)存中,程序執(zhí)行完畢,Java虛擬機(jī)停止的時(shí)候,內(nèi)存空間就被回收了。所以存儲的數(shù)據(jù)都是臨時(shí)性存儲的。

  4. 文件 ==存儲好多信息==

    文件是存儲在硬盤上的----》永久性保存。數(shù)據(jù)雖然安全,但是文件畢竟不在內(nèi)存中,需要通過IO操作文件。

字符集

字母:數(shù)字 符號------1字節(jié) 8bit

需要將除了字母以外的其他語言進(jìn)行字符編碼--->拆分和組合

拆分和組合的規(guī)則--所謂的字符編碼

常見的字符編碼

  • ASCII
  • ISO-8859-1
  • GB2312 GB18030 GBK BIG(繁體字)
  • Unicode
  • UTF-8

緩沖流

在管道內(nèi)增加緩沖的數(shù)據(jù)

讓我們使用流讀取的文字更加的流暢

BufferedInputStream/BufferOutputStream

BufferedReader/BufferedWriter

BufferedReader
        //每次讀取一行
        String value = readLine();
BufferedWriter
        write(String)
         //光標(biāo)移到下一行
         newLine()

對象流

ObjectInputStream/ObjectOutputStream

對象序列化/反序列化

對象的序列化:將一個(gè)完整的對象拆分成字節(jié)碎片,記錄在文件中

對象的反序列化:將文件記錄的對象,反過來組合成一個(gè)完整的對象

ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
    /*oos = new ObjectOutputStream(new FileOutputStream(new File("D:"+ File.separator + "lili.txt"), true));
            oos.writeObject(new Person("zhangsan", 80));
            oos.flush();*/

    ois = new ObjectInputStream(new FileInputStream("D:" + File.separator + "lili.txt"));
    Person o = (Person) ois.readObject();
    System.out.println(o.toString());
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (oos != null) {
            oos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        if (ois != null) {
            ois.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容