首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 修改文件中指定對象:RandomAccessFile 實現隨機讀寫定位

     編輯:程式設計綜合問答

需求:文件存儲多個對象,讀取其中一個、修改後寫回原位置。C 語言用 fseek 控制文件指針,Java 中用 RandomAccessFile 實現隨機訪問。

RandomAccessFile 核心方法

方法說明
seek(long pos)移動文件指針到指定字節偏移量
getFilePointer()獲取當前指針位置
readInt()/writeInt()讀寫基本類型(4 字節)
readUTF()/writeUTF()讀寫修改版 UTF-8 字符串
length()獲取文件長度

完整示例:修改文件中第 3 個對象的 name 字段

public class RandomAccessDemo {
    // 假設對象結構:int id(4B) + UTF name(變長) + double score(8B)
    // 為了定位,需要知道每條記錄的起始位置 → 建立索引或固定長度
    
    // 方案一:固定長度記錄(簡單、隨機訪問快)
    static final int RECORD_SIZE = 4 + 32 + 8; // id(4) + name(32固定) + score(8) = 44 字節
    
    public static void updateNameByIndex(String filePath, int index, String newName) throws IOException {
        try (RandomAccessFile raf = new RandomAccessFile(filePath, "rw")) {
            long pos = (long) index * RECORD_SIZE;
            raf.seek(pos);
            
            int id = raf.readInt(); // 讀取 id(可選驗證)
            raf.seek(pos + 4); // 跳過 id,定位到 name 起始
            
            // 寫入固定長度 name:不足補空格,超出截斷
            byte[] nameBytes = newName.getBytes(StandardCharsets.UTF_8);
            byte[] fixedName = new byte[32];
            System.arraycopy(nameBytes, 0, fixedName, 0, Math.min(nameBytes.length, 32));
            raf.write(fixedName);
            
            System.out.println("更新完成:索引 " + index + " 的 name → " + newName);
        }
    }
    
    // 方案二:變長記錄 + 索引文件(節省空間、適合大文件)
    // 主文件:順序存儲對象
    // 索引文件:每條記錄 8 字節 (long offset) → 隨機訪問索引獲取偏移量
}

關鍵注意事項

  • 模式 "rw":讀寫模式打開,"r" 只讀會拋異常
  • 字節對齊:基本類型按固定字節寫入(int=4, long=8, double=8),字符串必須固定長度或用長度前綴
  • 編碼一致:讀寫字符串統一用 UTF-8,避免中文亂碼
  • 併發安全:多線程訪問需外部加鎖(ReentrantLock 或 FileChannel.lock())
  • 文件擴展:seek 超過文件末尾再寫入會自動擴展文件(中間填 0)

對比:其他方案

方案優點缺點適用場景
RandomAccessFile真隨機訪問、不載入內存、支持大文件需手動管理結構、無緩衝、併發難固定結構、頻繁隨機修改、大文件
全部讀入內存修改再寫回代碼簡單、支持任意結構大文件 OOM、修改慢小文件、結構複雜、修改頻率低
SQLite / H2 內嵌數據庫SQL 查詢、事務、索引、併發引入依賴、有開銷結構變化大、需查詢、多線程
MemoryMappedFile (FileChannel.map)OS 級映射、極快、大文件友好映射大小固定、擴展麻煩超大文件、高性能讀寫

簡單場景用 RandomAccessFile 固定長度記錄 最直接;複雜業務上 SQLite 更省心。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved