隨機存取檔案流
阿新 • • 發佈:2020-08-09
# 隨機存取檔案流
RandomAccessFile類
## 概念
* RandomAccessFile宣告在java.io包下,但直接繼承於java.lang.Object類
* 這個類既可以讀也可以寫,可以作為一個輸入流,又可以作為一個輸出流
* RandomAccessFile類支援 “隨機訪問” 的方式,程式可以直接跳到檔案的任意地方來讀、寫檔案
* 支援只訪問檔案的部分內容
* 可以向已存在的檔案後追加內容
## 使用
### 構造器
>public RandomAccessFile(File file, String mode)
>public RandomAccessFile(String name, String mode)
建立RandomAccessFile類例項需要指定一個 mode 引數
mode引數指定 RandomAccessFile 的訪問模式:
* r: 以只讀方式開啟
* 不會建立檔案,而是會去讀取一個已經存在的檔案
* 如果讀取的檔案不存在則會出現異常。
* rw :開啟以便讀取和寫入
* 如果檔案不存在則會去建立檔案
* 如果存在則不會建立。
* rwd: 開啟以便讀取和寫入;同步檔案內容的更新
* rws: 開啟以便讀取和寫入; 同步檔案內容和元資料的更新
#### 說明
* 如果RandomAccessFile作為一個輸出流
* 寫出到的檔案如果不存在,則在執行過程中自動建立
* 寫出到的檔案存在,則會對原有檔案內容進行覆蓋,預設情況下從頭覆蓋
#### 程式碼實現
圖片的複製
```java
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("殷志源.png"), "r");
raf2 = new RandomAccessFile(new File("殷志源(1).png"), "rw");
byte[] buffer = new byte[1024];
int len;
while((len = raf1.read(buffer)) != -1){
raf2.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(raf1 != null)
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(raf2 != null)
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
```
### 實現資料的插入
RandomAccessFile物件包含一個記錄指標,用以標示當前讀寫處的位置。
RandomAccessFile類物件可以自由移動記錄指標:
* long getFilePointer():獲取檔案記錄指標的當前位置
* void seek(long pos):將檔案記錄指標定位到 pos 位置
#### 過程
原檔案的內容:abcdefghijklmn
要求:在c的後面新增xyz
過程
* 將指標一定到c後面的位置上(例子中“c”後面位置的角標為3)
* 儲存指標3後面的所有資料儲存
* 此時利用StringBuilder,因為其效率高,且是可變的字元序列
* 因為我們不清楚需要複製多少內容,所以利用StringBuilder中的如下構造器。其中長度為檔案的長度即可(File類中的length()方法)
>StringBuilder builder = new StringBuilder(int capacity);
* 調回指標,寫入要插入的內容
* 將儲存在StringBuilder中的資料寫入在檔案中
#### 程式碼實現
```java
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile("hi.txt","rw");
raf.seek(3);//將指標調到角標為3的位置
//儲存指標3後面的所有資料儲存到builder中
StringBuilder builder = new StringBuilder((int) new File("hi.txt").length());
byte[] buffer = new byte[20];
int len;
while((len = raf.read(buffer)) != -1){
builder.append(new String(buffer,0,len));
}
//調回指標,寫入“xyz”
raf.seek(3);
raf.write("xyz".getBytes());
//將StringBuilder中的資料寫入在檔案中
raf.write(builder.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(raf != null)
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
```
#### 執行結果
![o15m7.png](https://wx2.sbimg.cn/2020/08/09/o1