節點流和處理流(BufferedReader和BufferedWriter,BufferedInputStream和BufferedOutputStream,ObjectlnputStream和objectOutputStream)


一、基本介紹:

1、節點流可以從一個特定的數據源讀寫數據,如FileReader、 FileWriter 

如圖:字節流是直接對數據源(文件,數組之類存放數據的地方)進行操作

 

 

 

2.處理流(也叫包裝流)是"連接"在已存在的流(節 點流或處理流)之上,為程序提供
更為強大的讀寫功能,也更加靈活,如BufferedReader、BufferedWriter 

 

 

3、節點流和處理流的區別和聯系:

1).節點流是底層流/低級流,直接跟數據源相接。
2).處理流(包裝流)包裝節點流,既可以消除不同節點流的實現差異,也可以提供更方便的方法
來完成輸入輸出。
3).處理流(也叫包裝流)對節點流進行包裝,使用了修飾器設計模式,不會直接與數據
源相連[模擬修飾器設計模式]
●處理流的功能主要體現在以下兩個方面:
1.性能的提高:主要以增加緩沖的方式來提高輸入輸出的效率。
2.操作的便捷:處理流可能提供了-系列便捷的方法來一次輸入輸出大批量的數據, 使
用更加靈活方便

 

 

 

二、處理流-BufferedReader和BufferedWriter的使用

簡介:BufferedReader和BufferedWriter屬於字符流,是按照字符來讀取數據的

關閉時,只需要關閉外層流即可[可以調試看源碼:在底層會用close()關閉Reader]

注意:BufferedReader和BufferedWriter是安裝字符操作,不能操作二進制文件

常見的二進制文件【聲音,視頻,doc,pdf,圖片】

處理流的兩個實例:

BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferReader_ {
    public static void main(String[] args) throws IOException {
        //創建一個文件對象
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news3.txt";
        String line = null;
        //創建一個 BufferedReader的對象,並包裝一個FileReader在里面
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath1));
        while ((line = bufferedReader.readLine()) != null) {//readline表示讀取一行的字符串
            System.out.println(line);
        }
        //關閉BufferedReader處理流,只需要關閉外層即可,內層的FileReader會在底層自動關閉
        bufferedReader.close();

    }


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

public class BufferWeriter_ {
    public static void main(String[] args) throws IOException {
        //定義文件路徑
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news1.txt";

        //創建一個BufferWriter對象
//        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath1));//直接覆蓋原來內容
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath1,true));//在原來的內容上添加,添加到文章內容之后

        bufferedWriter.write("這里水太深你把握不住2.0。");
        bufferedWriter.newLine();//插入一個換行符
        bufferedWriter.write("這里水太深你把握不住3.0。");

        bufferedWriter.close();
    }
}

三、處理流:BufferedInputStream和BufferedOutputStream

1、BufferedInputStream:BufferedInputStream是字節流在創建BufferedInputStream

時,會創建一個內部緩沖區數組.

繼承實現圖

 

 

2、BufferedOutputStream:BufferedOutputStream是字節流,實現緩沖的輸出流,可以將多個字節寫入底層輸出流中,而不必對每次字節寫入調用底層系統

繼承實現圖

 

 

 使用BufferedInputStream和BufferedOutputStream2完成二進制文件的拷貝:

import java.io.*;

public class BufferedCopy {
    public static void main(String[] args) throws IOException {

    //復制的源地址和目的地址
    String srcPath = "C:\\Users\\wenman\\Desktop\\imageTest\\test33.jpg";
    String destPath = "C:\\Users\\wenman\\Desktop\\imageTest\\test11.jpg";
    //定義一個用於接收文件的byte[]數組和記錄數據大小的整數
        byte[] bytes = new byte[100];
        int dataLine = 0;
        //創建Buffered
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));

        while ((dataLine=bufferedInputStream.read(bytes))!= -1){
            bufferedOutputStream.write(bytes, 0, dataLine);
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();


    }

}

四。對象流-ObjectlnputStream和objectOutputStream

➢序列化和反序列化

1.序列化就是在保存數據時,保存數據的值和數據類型

2.反序列化就是在恢復數據時,恢復數據的值和數據類型
3.需要讓某個對象支持序列化機制,則必須讓其類是可序列化的,為了讓某個類是可序列化的,該
類必須實現如下兩個接口之- -:
➢Serializable//這是一個標記接口,沒有方法
➢Externalizable //該接口有方法需要實現,因此我們一般實現上面的Serializable接口

序列化反序列化類比圖如下:

 

 1、ObjectlnputStream和objectOutputStream基本介紹:

1).功能:提供了對基本類型或對象類型的序列化和反序列化的方法
2). ObjectOutputStream 提供序列化功能
3). ObjectlnputStream 提供反序列化功能

ObjectlnputStream的實現繼承圖:

 

 objectOutputStream的實現繼承圖:

 代碼實例:objectOutputStream

import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class ObjectOutput { public static void main(String[] args) throws IOException { //定義輸出的文件地址
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\data.dat"; //定義一個ObjectOutputStream對象,並包裝FileOutputStream的類
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath1)); objectOutputStream.writeInt(100); objectOutputStream.writeDouble(12.5); objectOutputStream.writeChar('A'); objectOutputStream.writeObject(new Dog("zhangsan", 20)); objectOutputStream.close(); } }

代碼實例:ObjectlnputStream

import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class ObjectInput { public static void main(String[] args) throws IOException, ClassNotFoundException { //文件路徑
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\data.dat"; ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(filePath1)); //讀取文件中存在的內容(內容讀取時,應當按照存放時的順序讀取文件)
        System.out.println(inputStream.readInt()); System.out.println(inputStream.readDouble()); System.out.println(inputStream.readChar()); //其中,Object的類型,應該是在整個包中可以訪問的,因為數據在存進文件時,類型所在的包也是保存進文件的 //所以在反序列化的時候,又會按照所記錄的包的類型去加載,包找不到就會加載錯誤,反序列化失敗
        Object dog = inputStream.readObject(); System.out.println(dog); // Dog dog1 = (Dog) dog; // System.out.println(dog1.getName() + "----" + dog1.getAge());
 inputStream.close(); } }

2、注意事項和細節說明

1)讀寫順序要一致
2)要求序列化或反序列化對象,需要實現 Serializable
3)序列化的類中建議添加SerialVersionUID,為了提高版本的兼容性
4)序列化對象時,默認將里面所有屬性都進行序列化,但除了static(靜態)或transient(臨時)修飾的成員5)序列化對象時,要求里面屬性的類型也需要實現序列化接口
6)序列化具備可繼承性,也就是如果某類已經實現了序列化,則它的所有子類也已經默認實現了序列化

 

標准輸入和標准輸出的編譯類型和運行類型:

 

 

 五、轉換流-lnputStreamReader和 OutputStreamWriter

1. InputStreamReader:Reader的子類,可以將InputStream(字節流)包裝成Reader(字符流)

指定文件讀取時的編碼:繼承實現圖


2.OutputStreamWriter:Writer的子類,實現將OutputStream(字節流)

指定文件讀取時的編碼:繼承實現圖

 

 

 


包裝成Writer(字符流)
3.當處理純文本數據時,如果使用字符流效率更高,並且可以有效解決中文
問題,所以建議將字節流轉換成字符流
4.可以在使用時指定編碼格式(比如utf-8, gbk , gb2312, ISO8859-1等)

引出問題:當文件中的編碼和讀取的編碼時出現亂碼問題:

 @Test
    public void Read1() throws IOException {
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news1.txt";
        byte[] bytes = new byte[100];
        int dataLine = 0;
        FileInputStream fileInputStream = new FileInputStream(filePath1);
        while ((dataLine = fileInputStream.read(bytes)) != -1){
            System.out.println(new String(bytes,0,dataLine));
        }
        fileInputStream.close();
    }

原文:這里水太深你把握不住。這里水太深你把握不住2.0。這里水太深你把握不住2.0。

這里水太深你把握不住3.0。

讀取后的內容:

 

 

 

 

 

 

 解決問題:

import org.junit.jupiter.api.Test; import java.io.*; public class BufferedReaderUtf { public static void main(String[] args) { String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news1.txt"; } @Test public void Read1() throws IOException { String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news1.txt"; byte[] bytes = new byte[100]; int dataLine = 0; FileInputStream fileInputStream = new FileInputStream(filePath1); while ((dataLine = fileInputStream.read(bytes)) != -1) { System.out.println(new String(bytes, 0, dataLine)); } fileInputStream.close(); } @Test public void Read2() throws IOException { //文件路徑
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news1.txt"; //給字節流設置一個讀取的編碼格式(在字節流中定義了一個新的流對象),指定編碼gbk
        InputStreamReader streamReader = new InputStreamReader(new FileInputStream(filePath1), "gbk"); //用一個處理流包裝字節流
        BufferedReader bufferedReader = new BufferedReader(streamReader);
//可以將上述兩行轉換為一行減少冗余
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath1)));
String data = null; //獲取文件內容輸出 while ((data = bufferedReader.readLine()) != null) { System.out.println(data); } bufferedReader.close();//關閉處理流,只需要關閉外層的,內層的會自動關閉  } }

結果:

OutputStreamWriter的使用:

import java.io.*; public class BufferedWriterUtf { public static void main(String[] args) throws IOException { //文件路徑
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\news2.txt"; String test = "這個世界上有很多"; //將一個輸出流轉換為一個字節轉換流,用一個處理流包裝起來,設置編碼方式為gbk,表示該文件內容為gbk
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath1),"gbk")); //輸出字符到指定文件
 bufferedWriter.write(test); //輸出一個換行符
 bufferedWriter.newLine(); //關閉外層處理流,內層字節流會自己關閉
 bufferedWriter.close(); } }

六、打印流:-PrintStream和PrintWriter:打印流只有輸出流,沒有輸入流

PrintStream的繼承實現圖

 

PrintWriter的實現繼承圖

 

 

代碼實例:

import org.junit.jupiter.api.Test;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;

public class Print {
    @Test
    public void printStream_() throws IOException {
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\note.txt";

        PrintStream out = System.out;
        //在默認情況下就輸出到控制台
        out.println("hello");
        //因為println在底層使用的是write,所有可以直接使用Write輸出
        out.write("hello".getBytes());
        System.setOut(new PrintStream(filePath1));
        System.out.println("hello,little");
    }


    @Test
    public void printWrite_() throws IOException {
        String filePath1 = "C:\\Users\\wenman\\Desktop\\test\\note.txt";

        PrintWriter printWriter = new PrintWriter(new FileWriter(filePath1));//輸出到文件
//        PrintWriter printWriter = new PrintWriter(System.out);//輸出到控制台
        printWriter.print("ghellouhadkuah");
        printWriter.close();
    }
}

七、Properties類

 基本介紹:

1)專門用於讀寫配置文件的集合類
配置文件的格式:
鍵=值
鍵=值
2)注意:鍵值對不需要有空格,值不需要用引號一起來。默認類型是String

3) Properties的常見方法

 ldad: 加載配置文件的鍵值對到Properties對象·

list:將數據顯示到指定設備
getProperty(key):根據鍵獲取值
setProperty(key,value):設置鍵值對到Properties對象
store:將Properties中的鍵值對存儲到配置文件,在idea中,保存信息到配置文件,如果含有中文,會存儲為unicode碼

http://tool.chinaz.com/tools/unicode.aspx unicode碼查詢工具

 


免責聲明!

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



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