04.JavaIO流問題

目錄介紹

  • 4.0.0.1 說一下Java IO裏面的常見類,字節流,字符流、接口、實現類、方法阻塞?
  • 4.0.0.2 什麼是比特(Bit),什麼是字節(Byte),什麼是字符(Char),它們長度是多少,各有什麼區別?
  • 4.0.0.3 字符流和字節流有什麼區別?如何選擇字節流或者字符流?什麼是緩衝區,有什麼作用?
  • 4.0.0.4 IO流中用到哪些模式?談一談IO流中用到的適配器模式和裝飾者模式的作用優勢?
  • 4.0.0.5 說一下對NIO的理解?NIO和IO的主要區別?NIO和IO如何影響應用程序的設計?
  • 4.0.1.1 對字節流進行大量的從硬盤讀取,要用那個流,爲什麼?

好消息

  • 博客筆記大彙總【15年10月到至今】,包括Java基礎及深入知識點,Android技術博客,Python學習筆記等等,還包括平時開發中遇到的bug彙總,當然也在工作之餘收集了大量的面試題,長期更新維護並且修正,持續完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計500篇[近100萬字],將會陸續發表到網上,轉載請註明出處,謝謝!
  • 鏈接地址:https://github.com/yangchong2...
  • 如果覺得好,可以star一下,謝謝!當然也歡迎提出建議,萬事起於忽微,量變引起質變!所有博客將陸續開源到GitHub!

4.0.0.1 說一下Java IO裏面的常見類,字節流,字符流、接口、實現類、方法阻塞?

  • 輸出流和輸入流

    • 輸入流就是從外部文件輸入到內存,輸出流主要是從內存輸出到文件。
  • IO裏面常見的類

    • IO流中有很多類,IO流主要分爲字符流和字節流。字符流中有抽象類InputStream和OutputStream,它們的子類FileInputStream,FileOutputStream,BufferedOutputStream等。字符流BufferedReader和Writer等。都實現了Closeable, Flushable, Appendable這些接口。程序中的輸入輸出都是以流的形式保存的,流中保存的實際上全都是字節文件。
  • IO流中方法阻塞

    • java中的阻塞式方法是指在程序調用改方法時,必須等待輸入數據可用或者檢測到輸入結束或者拋出異常,否則程序會一直停留在該語句上,不會執行下面的語句。比如read()和readLine()方法。
    • 技術博客大總結

4.0.0.2 什麼是比特(Bit),什麼是字節(Byte),什麼是字符(Char),它們長度是多少,各有什麼區別?

  • 什麼是比特(Bit)?

    • Bit最小的二進制單位 ,是計算機的操作部分 取值0或者1
  • 什麼是字節

    • Byte是計算機操作數據的最小單位由8位bit組成 取值(-128-127)
  • 什麼是字符

    • Char是用戶的可讀寫的最小單位,在Java裏面由16位bit組成 取值(0-65535)
  • 各有什麼區別

    • Bit 是最小單位 計算機 只能認識 0或者1

4.0.0.3 字符流和字節流有什麼區別?如何選擇字節流或者字符流?什麼是緩衝區,有什麼作用?

  • 字符流和字節流區別

    • 把二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一片二進制數據,不管輸入輸出設備是什麼,我們要用統一的方式來完成這些操作,用一種抽象的方式進行描述,這個抽象描述方式起名爲IO流,對應的抽象類爲OutputStream和InputStream ,不同的實現類就代表不同的輸入和輸出設備,它們都是針對字節進行操作的。
    • 在應用中,經常要完全是字符的一段文本輸出去或讀進來,用字節流可以嗎?計算機中的一切最終都是二進制的字節形式存在。對於“中國”這些字符,首先要得到其對應的字節,然後將字節寫入到輸出流。讀取時,首先讀到的是字節,可是我們要把它顯示爲字符,我們需要將字節轉換成字符。由於這樣的需求很廣泛,人家專門提供了字符流的包裝類。
    • 底層設備永遠只接受字節數據,有時候要寫字符串到底層設備,需要將字符串轉成字節再進行寫入。字符流是字節流的包裝,字符流則是直接接受字符串,它內部將串轉成字節,再寫入底層設備,這爲我們向IO設別寫入或讀取字符串提供了一點點方便。
    • 技術博客大總結
    • 字符流和字節流的使用非常相似,但是實際上字節流的操作不會經過緩衝區(內存)而是直接操作文本本身的,而字符流的操作會先經過緩衝區(內存)然後通過緩衝區再操作文件。
  • 如何選擇字節流或者字符流?

    • 字符流是由Java虛擬機將字節轉化爲2個字節的Unicode字符爲單位的字符而成的
    • 如果是音頻文件、圖片、歌曲,就用字節流好點(避免數據丟失)
    • 如果是關係到中文(文本)的,用字符流好點)
  • 什麼是緩衝區,有什麼作用?

    • 緩衝區就是一段特殊的內存區域,很多情況下當程序需要頻繁地操作一個資源(如文件或數據庫)則性能會很低,所以爲了提升性能就可以將一部分數據暫時讀寫到緩存區,以後直接從此區域中讀寫數據即可,這樣就顯著提升了性能。
    • 對於 Java 字符流的操作都是在緩衝區操作的,所以如果我們想在字符流操作中主動將緩衝區刷新到文件則可以使用 flush() 方法操作。

4.0.0.4 IO流中用到哪些模式?談一談IO流中用到的適配器模式和裝飾者模式的作用優勢?

  • IO流中用到哪些模式

    • 大概有裝飾者模式和適配器模式!
    • 要知道裝飾者模式和適配器模式的作用;其次,可以自己舉個例子把它的作用生動形象地講出來;最後,簡要說一下要完成這樣的功能需要什麼樣的條件。
  • 談一談IO流中用到的適配器模式和裝飾者模式的作用優勢

    • 裝飾器模式:就是動態地給一個對象添加一些額外的職責(對於原有功能的擴展)。

      //把InputStreamReader裝飾成BufferedReader來成爲具備緩衝能力的Reader。
      BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
      • 1.它必須持有一個被裝飾的對象(作爲成員變量)。
      • 2.它必須擁有與被裝飾對象相同的接口(多態調用、擴展需要)。
      • 3.它可以給被裝飾對象添加額外的功能。
      • 比如,在io流中,FilterInputStream類就是裝飾角色,它實現了InputStream類的所有接口,並持有InputStream的對象實例的引用,BufferedInputStream是具體的裝飾器實現者,這個裝飾器類的作用就是使得InputStream讀取的數據保存在內存中,而提高讀取的性能。
    • 適配器模式:將一個類的接口轉換成客戶期望的另一個接口,讓原本不兼容的接口可以合作無間。

      //把FileInputStream文件字節流適配成InputStreamReader字符流來操作文件字符串。
      FileInputStream fileInput = new FileInputStream(file); 
      InputStreamReader inputStreamReader = new InputStreamReader(fileInput);
      • 1.適配器對象實現原有接口
      • 2.適配器對象組合一個實現新接口的對象
      • 3.對適配器原有接口方法的調用被委託給新接口的實例的特定方法(重寫舊接口方法來調用新接口功能。)
      • 比如,在io流中,InputStreamReader類繼承了Reader接口,但要創建它必須在構造函數中傳入一個InputStream的實例,InputStreamReader的作用也就是將InputStream適配到Reader。InputStreamReader實現了Reader接口,並且持有了InputStream的引用。這裏,適配器就是InputStreamReader類,而源角色就是InputStream代表的實例對象,目標接口就是Reader類。
      • 適配器模式主要在於將一個接口轉變成另一個接口,它的目的是通過改變接口來達到重複使用的目的;而裝飾器模式不是要改變被裝飾對象的接口,而是保持原有的接口,但是增強原有對象的功能,或改變原有對象的方法而提高性能。
  • 用到設計模式優勢

    • 裝飾者模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個接口,裝飾對象持有被裝飾對象的實例(各種字符流間裝飾,各種字節流間裝飾)。
    • 技術博客大總結
    • 適配器模式就是將某個類的接口轉換成我們期望的另一個接口表示,目的是消除由於接口不匹配所造成的類的兼容性問題(字符流與字節流間互相適配)。

4.0.0.5 說一下對NIO的理解?NIO和IO的主要區別?NIO和IO如何影響應用程序的設計?

  • 說一下對NIO的理解?

    • 傳統的IO流是阻塞式的,會一直監聽一個ServerSocket,在調用read等方法時,它會一直等到數據到來或者緩衝區已滿時才返回。調用accept也是一直阻塞到有客戶端連接纔會返回。每個客戶端連接過來後,服務端都會啓動一個線程去處理該客戶端的請求。並且多線程處理多個連接。每個線程擁有自己的棧空間並且佔用一些CPU時間。每個線程遇到外部未準備好的時候,都會阻塞掉。阻塞的結果就是會帶來大量的進程上下文切換。
    • 對於NIO,它是非阻塞式,核心類:

      • 1.Buffer爲所有的原始類型提供 (Buffer)緩存支持。
      • 2.Charset字符集編碼解碼解決方案
      • 3.Channel一個新的原始I/O抽象,用於讀寫Buffer類型,通道可以認爲是一種連接,可以是到特定設備,程序或者是網絡的連接。
  • NIO和IO的主要區別?

    • 主要區別

      IO     NIO
      面向流     面向緩衝
      阻塞IO     非阻塞IO
      無     選擇器
    • 面向流與面向緩衝

      • Java IO和NIO之間第一個最大的區別是,IO是面向流的,NIO是面向緩衝區的。JavaIO面向流意味着每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩衝區。JavaNIO的緩衝導向方法略有不同。數據讀取到一個它稍後處理的緩衝區,需要時可在緩衝區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩衝區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩衝區時,不要覆蓋緩衝區裏尚未處理的數據。
    • 阻塞與非阻塞IO

      • Java IO的各種流是阻塞的。這意味着,當一個線程調用read()或write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了。JavaNIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什麼都不會獲取,而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可以繼續做其他的事情。非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。線程通常將非阻塞IO的空閒時間用於在其它通道上執行IO操作,所以一個單獨的線程現在可以管理多個輸入和輸出通道(channel)。
    • 選擇器

      • Java NIO的選擇器允許一個單獨的線程來監視多個輸入通道,你可以註冊多個通道使用一個選擇器,然後使用一個單獨的線程來“選擇”通道:這些通道里已經有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。
  • NIO和IO如何影響應用程序的設計?

    • 無論您選擇IO或NIO工具箱,可能會影響您應用程序設計的以下幾個方面:技術博客大總結

      • 1.對NIO或IO類的API調用。
      • 2.數據處理。
      • 3.用來處理數據的線程數。
    • API調用

      • 當然,使用NIO的API調用時看起來與使用IO時有所不同,但這並不意外,因爲並不是僅從一個InputStream逐字節讀取,而是數據必須先讀入緩衝區再處理。
    • 數據處理

      • 使用純粹的NIO設計相較IO設計,數據處理也受到影響。在IO設計中,我們從InputStream或 Reader逐字節讀取數據。
      • 請注意處理狀態由程序執行多久決定。換句話說,一旦reader.readLine()方法返回,你就知道肯定文本行就已讀完, readline()阻塞直到整行讀完,這就是原因。你也知道此行包含名稱;同樣,第二個readline()調用返回的時候,你知道這行包含年齡等。正如你可以看到,該處理程序僅在有新數據讀入時運行,並知道每步的數據是什麼。一旦正在運行的線程已處理過讀入的某些數據,該線程不會再回退數據(大多如此)。

4.0.1.1 對字節流進行大量的從硬盤讀取,要用那個流,爲什麼?

  • 對字節流進行大量的從硬盤讀取,要用那個流,爲什麼?

    • 因爲明確說了是對字節流的讀取,所以肯定是inputstream或者他的子類,又因爲要大量讀取,肯定要考慮到高效的問題,自然想到緩衝流。技術博客大總結
    • 用BufferedInputStream,原因:BufferedInputStream是InputStream的緩衝流,使用它可以防止每次讀取數據時進行實際的寫操作,代表着使用緩衝區。不帶緩衝的操作,每讀一個字節就要寫入一個字節,由於涉及磁盤的IO操作相比內存的操作要慢很多,所以不帶緩衝的流效率很低。帶緩衝的流,可以一次讀很多字節,但不向磁盤中寫入,只是先放到內存裏。等湊夠了緩衝區大小的時候一次性寫入磁盤,這種方式可以減少磁盤操作次數,速度就會提高很多!並且也可以減少對磁盤的損傷。

其他介紹

01.關於博客彙總鏈接

02.關於我的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章