1. 程式人生 > >Java之路:RandomAccessFile類

Java之路:RandomAccessFile類

Java提供了專門處理檔案的類,即RandomAccessFile(隨機訪問檔案)類。該類是Java語言中功能最為豐富的檔案訪問類

RandomAccessFile類支援“隨機訪問”方式,“隨機”是指可以跳轉到檔案的任意位置處讀寫資料

在訪問一個檔案的時候,不必把檔案從頭讀到尾,而是希望像訪問一個數據庫一樣“隨心所欲”地訪問一個檔案的某個部分,這時使用RandomAccessFile類就是最佳選擇。

RandomAccessFile物件類有個位置指示器,指向當前讀寫處的位置,當讀寫n個位元組後,檔案指示器將指向這n個位元組後面的下一個位元組處。剛開啟檔案時,檔案指示器指向檔案的開頭處,可以移動檔案指示器到新的位置,隨後的讀寫操作將從新的位置開始。

RandomAccessFile類在資料等長記錄格式檔案的隨機(相對順序而言)讀取時有很大的優勢,但該類僅限於操作檔案,不能訪問其他的IO裝置

,如網路、記憶體映像等。

RandomAccessFile類的構造方法如下所示:

//建立隨機儲存檔案流,檔案屬性由引數File物件指定
RandomAccessFile(File file, String mode) 

//建立隨機儲存檔案流,檔名由引數name指定
RandomAccessFile(String name, String mode) 

這兩個構造方法均涉及到一個String型別的引數mode,它決定隨機儲存檔案流的操作模式,下表列出了mode的值及對應的含義:

在這裡插入圖片描述

下 面 是 一 個 使 用 RandomAccessFile 的 例子,往檔案中寫入3名員工的資訊,然後按照第2名員工、第1名員工、第3名員工的先後順序讀出。RandomAccessFile可以以只讀或讀寫方式開啟檔案,具體使用哪種方式取決於使用者建立RandomAccessFile類物件的構造方法:

new RandomAccessFile(f,"rw");  //讀寫方式
new RandomAccessFile(f,"r");  //只讀方式

提示:當程式需要以讀寫的方式開啟一個檔案時,如果這個檔案不存在,程式會自動建立此檔案。

這裡還需要設計一個類來封裝員工資訊。一個員工資訊就是檔案中的一條記錄,而且必須保證每條記錄在檔案中的大小相同,也就是每個員工的姓名欄位在檔案中的長度是一樣的,這樣才能夠準確定位每條記錄在檔案中的具體位置。

假設name中有8個字元,少於8個則補空格(這裡用"\u0000"),多於8個則去掉後面多餘的部分。由於年齡是整型數,所以不管這個數有多大,只要它不超過整型數的範圍,在記憶體中都是佔4個位元組大小。

【示例】

package com.xy.io;

import java.io.RandomAccessFile;

public class RandomFileDemo {
	public static void main(String[] args) throws Exception {
		Employee e1 = new Employee("zhangsan", 23);
		Employee e2 = new Employee("lisi", 24);
		Employee e3 = new Employee("wangwu", 25);
		RandomAccessFile ra = new RandomAccessFile("C:\\Users\\XY\\Desktop\\employee.txt", "rw");

		
		ra.write(e1.name.getBytes());
		ra.writeInt(e1.age);
		ra.write(e2.name.getBytes());
		ra.writeInt(e2.age);
		ra.write(e3.name.getBytes());
		ra.writeInt(e3.age);
		ra.close();
		
		RandomAccessFile raf = new RandomAccessFile("C:\\Users\\XY\\Desktop\\employee.txt", "r");
		int len = 8;
		raf.skipBytes(12);	// 跳過第一個員工的資訊,姓名8位元組,年齡4位元組
		System.out.println("第2個員工的資訊:");
		String str = "";
		for(int i = 0; i < len; i++) {
			str += (char)raf.readByte();
		}
		System.out.println("name:" + str);
		System.out.println("age:" + raf.readInt());
		System.out.println("第1個員工的資訊:");
		raf.seek(0);	// 將檔案指標移動到檔案開始位置
		str = "";
		for(int i = 0; i < len; i++) {
			str += (char)raf.readByte();
		}
		System.out.println("name:" + str);
		System.out.println("age:" + raf.readInt());
		System.out.println("第3個員工的資訊:");
		raf.skipBytes(12);	// 跳過第二個員工的資訊,姓名8位元組,年齡4位元組
		str = "";
		for(int i = 0; i < len; i++) {
			str += (char)raf.readByte();
		}
		System.out.println("name:" + str);
		System.out.println("age:" + raf.readInt());
		raf.close();
	}
}

class Employee {
	String name;
	int age;
	final static int LEN = 8;
	public Employee(String name, int age) {
		if(name.length() > LEN) {
			name = name.substring(0, 8);
		}
		else {
			while(name.length() < LEN) {
				name = name + "\u0000";
			}
		}
		this.name = name;
		this.age = age;
	}
}

【結果】
在這裡插入圖片描述