隨機存取檔案流(雙性流)
阿新 • • 發佈:2021-01-12
隨機存取檔案流
RandomAccessFile類(雙性流)
-
RandomAccessFile宣告在java.io包下,單直接繼承於java.lang.Object類。並且它實現了DataInput,DataOutput這兩個介面,也就意味著這個類既可以讀也可以寫。
-
RandomAccessFile類支援“隨機訪問”的方式,程式可以直接跳到檔案的任意地方來讀,寫檔案
- 支援只訪問檔案的部分內容
- 可以向已存在的檔案後追加內容
-
RandomAccessFile物件包含一個記錄指標,用以標示當前讀寫的位置。
RandomAccessFile類物件可以自由移動記錄指標:
- long getFilePointer()
- void seek(long pos); 將檔案記錄指標定位到pos位置
- long getFilePointer()
-
構造器
public RandomAccessFile(File file,String mode); public RandomAccessFile(String name,String mode);
-
建立 RandomAccessFile 類例項需要指定一個mode引數,該引數指定RandomAccessFile的訪問模式:
- r:以只讀方式開啟
- rw:開啟以便讀取和寫入
- rwd:開啟以便讀取和寫入:同步檔案內容的更新
- rws:開啟以便讀取和寫入:同步檔案內容和元資料的更新
-
如果模式為只讀r。則不會建立檔案,而是會去讀一個已經存在的檔案,如果讀取的檔案不存在則會出現異常。如果模式為rw讀寫。如果檔案不存在則回去建立檔案,如果存在則不會建立(如果寫入檔案時則會對原始檔內容進行覆蓋預設從頭覆蓋)。
JDK1.6上面每次write資料時,”rw“模式,資料不會立即寫入到硬碟中;而”rwd“,資料會被立即寫入硬碟。如果寫資料過程發生異常,”rwd“模式中已被write的資料被儲存到硬碟,而”rw“這全部丟失。
-
我們可以用RandomAccessFile 這個類,來實現一個多執行緒斷點下載的功能,用過下載工具的朋友都知道,下載前都會建立兩個臨時檔案,一個是於被下載檔案相同的空檔案,另一個是記錄檔案指標的位置檔案,每次暫停的時候,都會儲存上一次的指標,然後斷點下載或上傳的功能。
程式碼例項
-
r--rw
import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAccessFileTest { public static void main(String[] args) { // demo1(); // demo2(); // demo3(); // demo4(); } //r--rw public static void demo1() { //jdk8 新特性 try (RandomAccessFile raf1 = new RandomAccessFile(new File("day30_IO/12.jpeg"), "r"); RandomAccessFile raf2 = new RandomAccessFile(new File("day30_IO/12.jpeg"), "rw")) { byte[] buffer = new byte[1024]; int len; while ((len = raf1.read(buffer)) != -1) { raf2.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } } //rw 如果檔案不存在則會建立檔案寫入資料/如果檔案存在則會對原有的檔案的覆蓋從開頭為位置 public static void demo2() { try ( RandomAccessFile raf1 = new RandomAccessFile("day30_IO/a.txt", "rw"); ) { raf1.write("xyz".getBytes()); } catch (IOException e) { e.printStackTrace(); } } public static void demo3() { try ( RandomAccessFile raf1 = new RandomAccessFile("day30_IO/a.txt", "rw"); ) { raf1.seek(3);//將指標調到角標為3的位置 raf1.write("xyz".getBytes()); } catch (IOException e) { e.printStackTrace(); } } //實現資料插入效果 public static void demo4() { try ( RandomAccessFile raf1 = new RandomAccessFile("day30_IO/a.txt", "rw"); ) { raf1.seek(3);//將指標調到角標為3的位置 //儲存指標3後面的所有資料到StringBuilder中 StringBuilder sb = new StringBuilder((int) new File("day30_IO/a.txt").length()); byte[] buffer = new byte[20]; int len; while ((len = raf1.read(buffer)) != -1) { sb.append(new String(buffer)); } //調回指標,寫入xyz raf1.seek(3); raf1.write("xyz".getBytes()); //將StringBuilder中資料寫入到檔案中 raf1.write(sb.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); } } } //擴充套件:將StringBuilder替換成ByteArrayOutputStream