日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Java Nio FileChannel堆內堆外數據讀寫全流程分析及使用

來源: 責編: 時間:2024-05-27 08:57:11 175觀看
導讀背景java nio中文件讀寫不管是普通文件讀寫,還是基于mmap實現零拷貝,都離不開FileChannel這個類。隨便打開RocketMQ 源碼搜索FileChannel。就可以看到使用頻率。圖片kafka也是。圖片所以在java中文件讀寫FileChannel尤

背景

java nio中文件讀寫不管是普通文件讀寫,還是基于mmap實現零拷貝,都離不開FileChannel這個類。13528資訊網——每日最新資訊28at.com

隨便打開RocketMQ 源碼搜索FileChannel。13528資訊網——每日最新資訊28at.com

就可以看到使用頻率。13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

kafka也是。13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

所以在java中文件讀寫FileChannel尤為重用。13528資訊網——每日最新資訊28at.com

java文件讀寫全流程

圖片圖片13528資訊網——每日最新資訊28at.com

這里說的僅僅是FileChannel基于堆內存(HeapByteBuffer)的文件讀寫。13528資訊網——每日最新資訊28at.com

如果是mmap或者堆外內存,可能有些步驟會省略,相當于有一些優化。13528資訊網——每日最新資訊28at.com

  1. FileChannel調用read,將HeapByteBuffer拷貝到DirectByteBuffer。
  2. JVM在native層使用read系統調用進行文件讀取, 這里需要進行上下文切換,從用戶態進入內核態。
  3. JVM 進程進入虛擬文件系統層,查看文件數據再page cache是否緩存,如果有則直接從page cache讀取并返回到DirectByteBuffer。
  4. 如果請求文件數據不在page caceh,則進入文件系統。通過塊驅動設備進行真正的IO,并進行文件預讀,比如讀取的文件可能只有1-10,但是會將1-20都讀取。
  5. 磁盤控制器DMA將磁盤中的數據拷貝到page cache中。這里發生了一次數據拷貝(非CPU拷貝)。
  6. CPU將page cache數據拷貝到DirectByteBuffer,因為page cache屬于內核空間,JVM進程無法直接尋址。這里是發生第二次數據拷貝。
  7. JVM進程從內核態切換回用戶態,這里如果使用的是堆內存(HeapByteBuffer),實際還需要將堆外內存DirectByteBuffer拷貝到堆內存(HeapByteBuffer)。

FileChannel讀寫文件(非MMAP)

public static void main(String[] args) {        String filename = "小奏技術.txt";        String content = "Hello, 小奏技術.";        // 寫入文件        writeFile(filename, content);        // 讀取文件        System.out.println("Reading from file:");        readFile(filename);    }    public static void writeFile(String filename, String content) {        // 創建文件對象        File file = new File(filename);        // 確保文件存在        if (!file.exists()) {            try {                boolean created = file.createNewFile();                if (!created) {                    System.err.println("Unable to create file: " + filename);                    return;                }            } catch (Exception e) {                System.err.println("An error occurred while creating the file: " + e.getMessage());                return;            }        }        // 使用FileChannel寫入文件        try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");             FileChannel fileChannel = randomAccessFile.getChannel()) {            ByteBuffer buffer = ByteBuffer.allocate(content.getBytes().length);            buffer.put(content.getBytes());            buffer.flip(); // 切換到讀模式            while (buffer.hasRemaining()) {                fileChannel.write(buffer);            }        } catch (Exception e) {            System.err.println("An error occurred while writing to the file: " + e.getMessage());        }    }    public static void readFile(String filename) {        // 使用FileChannel讀取文件        try (RandomAccessFile randomAccessFile = new RandomAccessFile(filename, "r");             FileChannel fileChannel = randomAccessFile.getChannel()) {            ByteBuffer buffer = ByteBuffer.allocate((int) fileChannel.size());            while (fileChannel.read(buffer) > 0) {                // Do nothing, just read            }            // 切換到讀模式            buffer.flip();            /* while (buffer.hasRemaining()) {                System.out.print((char) buffer.get());            }*/            Charset charset = StandardCharsets.UTF_8;             String fileContent = charset.decode(buffer).toString();            System.out.print(fileContent);        } catch (Exception e) {            System.err.println("An error occurred while reading the file: " + e.getMessage());        }    }

這里需要注意的一個細節 我們分配的內存的方式是:13528資訊網——每日最新資訊28at.com

ByteBuffer.allocate()

這里我們可以進入看看源碼:13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

實際構造的是HeapByteBuffer,也就是JVM的堆內存。13528資訊網——每日最新資訊28at.com

如果我們使用:13528資訊網——每日最新資訊28at.com

ByteBuffer.allocateDirect()

圖片圖片13528資訊網——每日最新資訊28at.com

則構造的是堆外內存DirectByteBuffer。13528資訊網——每日最新資訊28at.com

HeapByteBuffer和DirectByteBuffer文件讀寫區別

我們看看FileChannel read方法:13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

發現IO相關的處理被封裝在IOUtil,我們繼續看看IOUtil的write方法:13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

可以看到如果是DirectBuffer則可以直接寫。如果是HeapByteBuffer則需要轉換為DirectByteBuffer。13528資訊網——每日最新資訊28at.com

圖片圖片13528資訊網——每日最新資訊28at.com

為什么要在DirectByteBuffer做一層轉換

主要是HeapByteBuffer受JVM管理,也就是會受到GC影響。如果在進行native調用的時候發生了GC,會導致HeapByteBuffer的內容出現錯誤。具體詳細的說明可以看看這篇MappedByteBuffer VS FileChannel:從內核層面對比兩者的性能差異。講解的非常清晰。13528資訊網——每日最新資訊28at.com

參考

  • MappedByteBuffer VS FileChannel:從內核層面對比兩者的性能差異 

本文鏈接:http://www.www897cc.com/showinfo-26-90858-0.htmlJava Nio FileChannel堆內堆外數據讀寫全流程分析及使用

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Wire:Go語言依賴注入的利器

下一篇: 避免鎖表:為Update語句中的Where條件添加索引字段

標簽:
  • 熱門焦點
  • 5月iOS設備性能榜:M1 M2依舊是榜單前五

    和上個月一樣,沒有新品發布的iOS設備性能榜的上榜設備并沒有什么更替,僅僅只有跑分變化而產生的排名變動,剛剛開始的蘋果WWDC2023,推出的產品也依舊是新款Mac Pro、新款Mac Stu
  • SpringBoot中使用Cache提升接口性能詳解

    環境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPASpring 框架從 3.1 開始,對 Spring 應用程序提供了透明式添加緩存的支持。和事務支持一樣,抽象緩存允許一致地使用各
  • 使用LLM插件從命令行訪問Llama 2

    最近的一個大新聞是Meta AI推出了新的開源授權的大型語言模型Llama 2。這是一項非常重要的進展:Llama 2可免費用于研究和商業用途。(幾小時前,swyy發現它已從LLaMA 2更名為Lla
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問我,如何才能學好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現百度,功能雖然實現了,但是為什么用這個?不知道。更別說效率問題了~下次再遇到,
  • 重估百度丨大模型,能撐起百度的“今天”嗎?

    自象限原創 作者|程心 羅輯2023年之前,對于自己的“今天”,百度也很迷茫。“新業務到 2022 年底還是 0,希望 2023 年出來一個 1。”這是2022年底,李彥宏
  • 華為開發者大會2023日程公開:開設鴻蒙HarmonyOS 4體驗區

    IT之家 7 月 31 日消息,華為今日公布了 HDC.Together 開發者大會 2023 的詳細日程。整場大會將于 8 月 4 日-6 日之間舉行,屆時將發布最新一代鴻蒙 H
  • 三星顯示已開始為AR設備研發硅基LED微顯示屏

    7月18日消息,據外媒報道,隨著蘋果首款頭顯產品Vision Pro在6月份正式推出,AR/VR/MR等頭顯產品也就將成為各大公司下一個重要的競爭領域,對顯示屏這一關
  • 首發天璣9200+ iQOO Neo8系列發布首銷售價2299元起

    2023年5月23日晚,iQOO Neo8系列正式發布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro強悍登場,限時售價3099元起;價位段最強性能手機iQOO Neo8同期上市
  • 回歸OPPO兩年,一加贏了銷量,輸了品牌

    成為OPPO旗下主打性能的先鋒品牌后,一加屢創佳績。今年618期間,一加手機全渠道銷量同比增長362%,憑借一加 11、一加 Ace 2、一加 Ace 2V三款爆品,一加
Top 主站蜘蛛池模板: 伊春市| 柳河县| 呈贡县| 大埔县| 寻乌县| 玉环县| 永泰县| 东山县| 清苑县| 延庆县| 靖边县| 烟台市| 噶尔县| 霞浦县| 海晏县| 十堰市| 宣汉县| 迁西县| 永吉县| 巨野县| 息烽县| 昂仁县| 饶阳县| 游戏| 张家口市| 汪清县| 无极县| 贵南县| 罗甸县| 泸水县| 楚雄市| 凤翔县| 古丈县| 三河市| 红河县| 兴城市| 雅江县| 辽中县| 西青区| 雷州市| 昂仁县|