Java有兩種不同的輸入輸出API,分別是IO(Input/Output)和NIO(New Input/Output)。雖然兩者都提供了對文件和網絡操作的支持,但在很多方面有很大不同。本文將從以下幾個方面詳細闡述兩者的區別。
一、Java IO和NIO的整體區別
IO和NIO最重要的區別在於它們處理數據的方式和實現機制不同。Java IO是面向流的,數據流向一個固定的方向:即從源到目的地。數據可以從一個InputStream(輸入流)讀取,寫入到一個OutputStream(輸出流)。所有的傳輸或處理數據的單元都是一個字節。
NIO第一次引入了緩衝區的概念,以提高速度和效率。它提供了對通道(Channel)的支持,數據可以從通道讀取到緩衝區中,或者從緩衝區寫入到通道中。通道本身就是雙向的,可以用於讀寫兩個方向。此外,緩衝區允許用戶使用內存映射文件(MappedByteBuffer)來讀寫文件,以便減少IO操作。
二、Java IO和NIO的基本類庫不同
Java IO提供了InputStream、OutputStream、Reader和Writer等幾個重要的類,可以實現從文件或網絡流讀取數據,或者向文件流或網絡流寫入數據。而NIO則提供了ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer和DoubleBuffer等緩衝區,以便讀寫數據。它還提供了BufferedChannel、Selector、ServerSocketChannel和SocketChannel等操作緩衝區的類。
三、Java IO和NIO的阻塞和非阻塞機制不同
Java IO是阻塞的。即當IO操作時,程序會一直等待,直到數據已經可用才會繼續執行下去。這意味着,一個線程在一個時間點只能讀取或寫入一個請求,不能同時處理多個請求。
NIO則提供了非阻塞I/O操作。基於NIO的操作可以大大提高處理請求的效率。非阻塞操作允許線程在等待請求完成時執行其他操作,從而使一個線程可以同時處理多個請求。
四、Java IO和NIO的多路復用機制不同
Java IO通過Socket類來實現TCP/IP網絡通信。在Java IO中,線程必須等待請求I/O處理完成,這會導致線程的數量必須等於I/O請求的數量,從而開銷巨大。
NIO則使用了基於選擇器(Selector)的多路復用機制來避免為每個連接分配一個線程。這種機制是說,在一個線程中,可以通過選擇器同時處理多個連接請求,並在每個請求就緒時進行處理。這可以輕鬆地讓一個線程來管理多個連接,並顯著減少線程的開銷。
五、Java IO和NIO的擴展性差異
Java IO的線程模型不適合高並發的情況,因為線程開銷很大,並且需要為每個連接分配一個線程。這會導致系統的性能受限。
NIO中的線程模型適合高並發請求。每個線程可以處理多個請求,從而保持了內存的穩定性。
六、應用實例——文件讀取功能
下面我們就來看看Java IO和NIO在文件讀取功能上的不同:
Java IO實現文件讀取:
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class FileReading { public static void main(String[] args) { File file = new File("test.txt"); try (FileReader fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(fileReader)) { String line = null; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
NIO實現文件讀取:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; public class FileReadingNIO { public static void main(String[] args) { Path path = Paths.get("test.txt"); try (Stream lines = Files.lines(path)) { lines.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } } }
七、小結
本文介紹了Java IO和NIO之間的不同之處,並且提供了一個應用實例,以便更好地理解它們的區別和使用場景。在選擇使用API時,我們應該根據實際需求和情況,選擇一個更適合我們的API。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/310113.html