【Java學習筆記(一百一十九)】之 記憶體對映檔案,緩衝區,檔案加鎖
本文章由公號【開發小鴿】釋出!歡迎關注!!!
老規矩–妹妹鎮樓:
一. 記憶體對映檔案
(一) 概述
大多數作業系統都可以利用虛擬記憶體實現將一個檔案或檔案的一部分對映到記憶體中,然後,這個檔案就可以被當做記憶體陣列一樣訪問,這比傳統的檔案操作要快很多,從效率來看,記憶體對映 > 帶緩衝的輸入流 > 普通輸入流 > 隨機訪問檔案。
(二) 對映過程
首先,從檔案中獲得一個通道,通道是用於磁碟檔案的一種抽象,它可以使我們訪問諸如 記憶體對映,檔案加鎖機制 以及 檔案間快速資料傳遞等作業系統特性。
FileChannel channel = FileChannel.open(path, options);
然後,通過呼叫FileChannel類的map方法從這個通道中獲得一個ByteBuffer,可以指定想要對映的檔案區域與對映模式,支援的模式有三種:
FileChannel.MapMode.READ_ONLY : 只讀緩衝區
FileChannel.MapMode.READ_WRITE: 可讀寫緩衝區,任何修改都會在某個時刻寫回到檔案中
FileChannel,MapMode.PRIVATE: 可寫緩衝區,但是不會傳播到檔案中
MappedByteBuffer buffer = channel.map (FileChannel.MapMode.READ_ONLY, 0, length);
二. 緩衝區
(一) 概述
使用記憶體對映時,我們建立了單一的緩衝區橫跨整個檔案或者感興趣的檔案區域,我們還可以使用更多的緩衝區來讀寫大小適度的資訊塊。緩衝區是由相同型別的數值構成的陣列,Buffer類是一個抽象類,它有眾多的具體子類,如ByteBuffer, CharBuffer, DoubleBuffer, IntBuffer, LongBuffer 和 ShortBuffer。
(二) 緩衝區的常用配置
容量,永遠不變,表示緩衝區的最大值;
讀寫位置, 下一個值將在這裡讀寫;
界限,超過它進行讀寫沒有意義;
可選的標記, 用於重複一個讀入或寫出操作;
0 < 標記 < 讀寫位置 < 界限 < 容量
使用緩衝區的目的是執行“寫入,然後讀取”的迴圈,即首先寫入緩衝區,然後從緩衝區中讀取。
(三) 常用方法
1. clear()
將位置復位到0,界限設定到容量,為寫出做好準備。
2. flip()
界限設定到位置,位置復位到0,為讀入做好準備。
3. remaining()
返回剩餘可讀入或可寫出的值的數量,即界限與位置之間的差異。
三. 檔案加鎖機制
(一) 概述
當多個併發的程式需要修改同一個檔案時,會有執行緒安全問題, 因此採用檔案鎖控制對檔案或檔案中某個範圍的位元組訪問。
(二) 加鎖
要鎖定一個檔案,可以呼叫FileChannel類的lock或tryLock方法:
FileChannel channel = FileChannel.open(path);
FileLock lock = channel.lock();
FileLock lock = channel.lock();
lock()會阻塞直至可獲得鎖,tryLock()會立即返回鎖或者null。這個檔案將會保持鎖定狀態,直到通道關閉,或者在鎖上呼叫了release()方法釋放鎖。
還可以只鎖定檔案的一部分,並制定是否共享鎖,如果共享,則允許多個執行緒從檔案中讀入,並組織任何執行緒獲得獨佔的鎖。
FileLock lock(long start, long size, boolean shared)