13Java進階——IO、線程

1 字節緩衝流

BufferInputStream 將建立一個內部的緩衝區數組,內部緩衝區數組將根據須要從包含的輸入流中從新填充,一次能夠讀取多個字節html

BufferOutputStream 該類實現緩衝輸出流。 經過設置這樣的輸出流,應用程序能夠向底層輸出流寫入字節,而沒必要爲寫入的每一個字節致使底層系統的調用java

構造方法:傳入字節流,能夠指定緩衝區大小數組

bos.write("hello\r\n".getBytes(StandardCharsets.UTF_8));安全

BufferedOutputStream 內部帶有緩衝區 寫數據的時候 先寫出到緩衝區,緩衝區寫滿的時候 ,纔會將緩衝區的內容寫出到磁盤 調用flush方法 只刷新緩衝流 但不釋放資源 close方法 在關閉流 釋放資源以前 會先刷新緩衝流網絡

爲何緩衝流的構造方法中須要的是一個字節流,而不是具體的文件或者路徑呢?多線程

字節緩衝流僅僅提供緩衝區,而真正的讀寫數據還的移開基本的字節流對象進行操做。併發

2 字符流

2.1 爲何出現字符流

因爲字節流操做中文不是特別方便,因此就出現了字符流jvm

字符流 = 字節流 +字符集ide

中文字節存儲方式編碼

用字節流複製文本文件時,文本文件也會有中文,可是沒有問題,緣由就是最終底層操做會自動的進行字節拼接成中文。

如何識別中文?

漢字在存儲的時候 不管使用那種編碼存儲 第一個字節都是負數。

2.2. 字符串中的編碼和解碼的問題

編碼就指的是將字符轉換成字節

string.getBytes(),參數可指定String 字符集名

默認的編碼 UTF-8

// 解碼 編碼和解碼必須使用相同的碼錶 不然會出現中文亂碼

解碼: 將字節數組轉換爲字符

String(byte[] bytes, String charsetName)構造一個新的String由指定用指定的字節的數組解碼charset

2.3. 字符流中的編碼問題

字符流的抽象基類:

Reader 字符輸入流的抽象基類 編碼

Writer 字符輸出流的抽象基類 解碼

字符流中和編碼相關的類:

  • InputStreamReader是從字節流到字符流的橋:它讀取字節,並使用指定的charset將其解碼爲字符 。 它使用的字符集能夠由名稱指定,也能夠被明確指定,或者能夠接受平臺的默認字符集。

  • OutputStreamWriter是字符的橋樑流以字節流:向其寫入的字符編碼成使用指定的字節charset 。 它使用的字符集能夠由名稱指定,也能夠被明確指定,或者能夠接受平臺的默認字符集。

構造方法:字節流+可選字符集名

  • 使用字符流完成對於中文的寫和讀

    2.4 字符流讀寫的方式

    寫:write(字符數組/字符串/字符,起始位置)

    刷新和關閉close(),flush()

    讀:read(字符/字符數組,起始位置)

字符流自帶緩衝區

2.5 字符流操做的便捷類

FileReader 是InputStreamReader的簡潔形式

FileWriter 是OutputStreamReader的簡潔形式

2.6 字符緩衝流

BufferedReader

  • 從字符輸入流讀取文本,緩衝字符,以提供字符,數組和行的高效讀取。能夠指定緩衝區大小,或者可使用默認大小。

    BufferedReader(Reader in) 建立使用默認大小的輸入緩衝區的緩衝字符輸入流。

    readline()讀一行

BufferedWriter

  • 將文本寫入字符輸出流,緩衝字符,以提供單個字符,數組和字符串的高效寫入。

    能夠指定緩衝區大小,或者能夠接受默認大小。

    BufferedWriter(Writer out) 建立使用默認大小的輸出緩衝區的緩衝字符輸出流。

    newLine()寫分隔符

2.7 IO流小結

image-20210729105134952

字節流能夠賦值文件數據,有四種方式通常採用字節緩衝流一次去屑一個字節數組的形式。

3 標準輸入輸出流

PrintStream:err、out

InputStream:in

3.1.標準輸入流(字節流)

    public static void main(String[] args) throws IOException {
        //字節流
        InputStream is = System.in;// 字節輸入流的數據來源來自標準輸入設備鍵盤
        BufferedReader br = new BufferedReader(new InputStreamReader(isr));
        System.out.println("請輸入一個整數:");
        int i= Integer.parseInt(br.readLine());
        System.out.println("您輸入的整數爲:"+(i + 1));
        //以上代碼就是本身實現了鍵盤錄入字符串和整數的方法   這樣寫起來有點麻煩,所以Java提供了
        Scanner sc = new Scanner(System.in);
    }

3.2. 標準輸出流

PrintStream ps = System.out;

4 打印流

打印流分爲:

  • 字節 打印流 PrintStream

  • 字符打印流 PrintWtriter

打印流的特色:

只負責數據的輸出 不能讀取數據

有一些特有的方法 println() print()

5 對象的序列化流

對象序列化: 就是將對象保存到磁盤或者在網絡中傳輸對象 爲了對象保存的正確性 和傳輸的安全性,須要對對象進行編碼處理,那麼把這種處理方式稱爲對象的序列化

反序列化:將序列化的對象解析爲原對象的過程 就稱爲反序列化

  • ObjectOutputStream oos.writeObject(obj);

  • ObjectInputStream ois.readObject();再強制轉型

對於對象傳輸 對象必須實現java.io.Serializable接口

6 Porperties

Porperties是Map集合的一個實現類

Properties prop = new Properties(); prop.put(k,v); prop.entrySet();

Porperties能夠保存到流中或者從流中加載。 屬性列表中的鍵及其對應的值都是字符串

prop.getProperty(k) prop.setProperty(k,v)

prop.load(輸入字節流/reader) prop().store(輸出字節流/writer,註解默認爲null)

7 多線程

7.1 進程 線程 程序

程序: 是爲了完成特定任務 用某種語言編寫的一組指令的集合。指的一段靜態。

進程:是程序的一次執行過程,或是正在運行的一個程序,是一個動態的過程:有他自身的產生 存在 以及消亡的過程--生命週期

程序是靜態的 進程是動態的進程做爲資源分配單位,系統在運行時會爲每一個進程分配不一樣的內存區域。

線程(thread) 進程進一步細化就是線程,是一個程序內部的一條執行路徑。

若一個進程同一時間並行執行多個線程,就是支持多線程。

線程做爲調度和執行的單位,每一個線程擁有獨立的運行棧和程序計數器,線程的切換開銷比較小。

一個進程中的多個線程共享相同的內存單元和內存地址空間,他們從一個堆中分配對象,能夠訪問相同的變量和對象。這就是的線程間的通訊變得簡便和高效。但多個線程操做共享的系統資源可能會帶來安全隱患。

單核CPU和多核CPU

在java中 一個程序至少有三個線程組成, 主線程(main) 垃圾回收線程(gc) 異常處理線程。

並行和併發:

  • 並行:多個CPU同時執行多個任務

  • 併發: 一個CPU在同一時刻,同時處理多個任務。

使用多線程的優勢:

1 提升了應用程序的響應。

2 提升了計算機CPU的利用率

3 改善程序結構。

什麼時候須要多線程?

  • 程序須要同時執行兩個或多個任務

  • 程序須要實現一些須要等待的任務的時候:如:用戶輸入,文件讀寫 網絡操做等。

  • 須要一些後臺運行的程序時

7.2 實現多線程

建立一個新的執行線程有兩種方法。

  • 一個是將一個類聲明爲Thread的子類。 這個子類應該重寫Thread的run方法 。 而後能夠分配並啓動子類的實例

  • 另外一種方法來建立一個線程是聲明實現類Runnable接口。 那個類而後實現了run方法。 而後能夠分配類的實例,在建立Thread時做爲參數傳遞,並啓動

7.2.1 實現線程的方式一: 繼承Thread類

爲何要重寫run方法?

由於run方法是用來封裝被線程執行的代碼的。

run方和start方法的區別?

run()封裝了線程執行的代碼,直接調用的,至關於普通方法調用。

start方法 啓動線程,而後由jvm調用此線程的run方法

7.2.2 實現線程的方式二: 實現Runnable接口

  • public interface Runnable

    Runnable接口應由任何類實現,其實例將由線程執行。 該類必須定義一個無參數的方法,稱爲run

    Runnable r = new MyRannable(); Thread t1 = new Thread(r);

    t1.start();

或 new Thread(new Runnable(){@Override public void run(){sout;} }).start();

7.3 設置和獲取線程的名稱

Thread(name):有參構造,參數是線程的名字

th.setName(name);

Thread.currentThread();返回當前正在執行的線程對象的引用。

th.getName();

7.4 線程的優先級

th.getPriority();

th.setPriority(pri);

  • 每一個線程都有優先權。 具備較高優先級的線程優先於優先級較低的線程執行

線程的兩種調度模型

分時調度: 全部線程輪流實現CPU的使用權,平均分配每一個線程佔有CPU的時間片

搶佔式調度: 優先讓優先級高的線程使用CPU,若是線程的優先級相同,那麼會隨機選擇一個。優先級高的線程得到CPU執行權的機率更高。

java是的是搶佔式的調度模型。

線程的默認優先級爲5,線程的優先級的範圍爲1(小)--10(大)

相關文章
相關標籤/搜索