Java中RandomAccessFile读写XML文件时读取数据异常求助
问题描述
使用RandomAccessFile读写员工数据(文件命名为XML格式,但实际是二进制存储)时,仅第一行数据读取正确,后续行数据完全混乱。
写入代码
public static void main(String[] args) throws IOException { File file = new File("C:\\Test\\employee.XML"); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); String nameEmp[] = {"Name A", "Name B", "Name C", "Name D", "Name E"}; String addEmp[] = {"Address A", "Address B", "Address C", " Address D", "Address E"}; int saleEmp[] = {2000,1232,7653,1236,3452}; int comEmp[] = {400,100,3000,300,500}; StringBuffer buffer; StringBuffer buffer1; for (int i=0;i< nameEmp.length; i++){ randomAccessFile.writeInt(i+1); buffer = new StringBuffer( nameEmp[i]); buffer.setLength(10); randomAccessFile.writeChars(buffer.toString()); buffer1 = new StringBuffer( addEmp[i]); buffer1.setLength(100); randomAccessFile.writeChars(buffer1.toString()); randomAccessFile.writeInt(saleEmp[i]); randomAccessFile.writeInt(comEmp[i]); } randomAccessFile.close(); }
读取代码(原错误版本)
public static void main(String[] args) throws IOException { File file = new File("C:\\Test\\employee.XML"); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); int codeEmp, position = 0; char nameEmp[] = new char[10]; char addEmp[] = new char [100]; int saleEmp , comEmp; for(;;){ randomAccessFile.seek(position); codeEmp = randomAccessFile.readInt(); for (int i = 0; i < nameEmp.length; i++) { nameEmp[i] = randomAccessFile.readChar(); } String nameEmpS= new String(nameEmp); for (int i = 0; i < addEmp.length; i++) { addEmp[i] = randomAccessFile.readChar(); } String addEmpS= new String(addEmp); saleEmp =randomAccessFile.readInt(); comEmp=randomAccessFile.readInt(); System.out.println("Cod Emp: " + codeEmp + ", nombre: " +nameEmpS+ ", dirección: "+addEmpS+ ", sale: " + saleEmp+ ", comisión: " + comEmp ); position= position + 36; if (randomAccessFile.getFilePointer()==file.length())break; } randomAccessFile.close(); }
错误输出
Cod Emp: 1, nombre: Name A , dirección: Address A , sale: 2000, comisión: 400
Cod Emp: 7536672, nombre: A , dirección: Name B Ad, sale: 6553714, comisión: 6619251
Cod Emp: 0, nombre: , dirección: Ɛ Name B Address B , sale: 0, comisión: 0
问题根源
核心错误是手动维护的记录步长position +=36完全不符合实际每条记录的字节数:
writeInt每次写入4字节writeChars写入的每个char占2字节,10个字符的名字占20字节,100个字符的地址占200字节- 两个
writeInt共8字节
单条记录总字节数:4 + 20 + 200 + 8 = 232字节,原代码用36作为步长,导致每次seek到错误位置,后续读取的数据完全错位。
修复方案
有两种可靠的修复方式:
方式1:自动跟踪文件指针,无需手动计算步长
直接通过getFilePointer()判断是否读取到文件末尾,去掉手动维护的position变量:
public static void main(String[] args) throws IOException { File file = new File("C:\\Test\\employee.XML"); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); int codeEmp; char nameEmp[] = new char[10]; char addEmp[] = new char[100]; int saleEmp, comEmp; // 通过文件指针位置判断是否读完所有记录 while (randomAccessFile.getFilePointer() < file.length()) { codeEmp = randomAccessFile.readInt(); // 读取名字 for (int i = 0; i < nameEmp.length; i++) { nameEmp[i] = randomAccessFile.readChar(); } String nameEmpS = new String(nameEmp).trim(); // 移除多余填充空格 // 读取地址 for (int i = 0; i < addEmp.length; i++) { addEmp[i] = randomAccessFile.readChar(); } String addEmpS = new String(addEmp).trim(); saleEmp = randomAccessFile.readInt(); comEmp = randomAccessFile.readInt(); System.out.println("Cod Emp: " + codeEmp + ", nombre: " + nameEmpS + ", dirección: " + addEmpS + ", sale: " + saleEmp + ", comisión: " + comEmp); } randomAccessFile.close(); }
方式2:使用正确的记录步长
如果坚持手动维护position,将步长改为正确的232字节:
// 替换原代码中的position更新逻辑 position = position + 232;
额外优化建议
- 将记录的字节数定义为常量(如
private static final int RECORD_SIZE = 232;),避免硬编码出错 - 读取字符串后调用
trim()移除写入时填充的多余空格,让输出更整洁
内容的提问来源于stack exchange,提问作者Tuan Do

