You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java:使用RandomAccessFile时如何正确分割文本文件的换行?

问题分析与解决方案

核心错误原因

  • raf.readLine() 每次只读取单独一行内容,返回的字符串里不含换行符\n,所以str.split("\n")得到的数组永远只有1个元素,直接取data[1]必然触发数组越界。
  • 你的文本是每4行对应一组数据(名称、楼层、价格、位置),但代码里每次读一行就处理,逻辑完全错配,导致floors等变量要么取到不存在的数组元素,要么内容不符合预期。

修复后的代码示例

import java.io.RandomAccessFile;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;

public class FileProcessor {
    public static void main(String[] args) {
        DecimalFormat df = new DecimalFormat("#.00");
        try (RandomAccessFile raf = new RandomAccessFile("domy.txt", "rw")) {
            String str;
            // 每4行读取一组完整数据
            while ((str = raf.readLine()) != null) {
                String name = str;
                String floors = raf.readLine();
                String price = raf.readLine();
                String location = raf.readLine();
                
                // 防止文件末尾数据不完整,提前终止
                if (floors == null || price == null || location == null) {
                    break;
                }

                System.out.println(name + " " + floors + " " + price + " " + location);

                if ("1".equals(floors) && "Wies".equals(location)) {
                    int floorsInt = Integer.parseInt(floors);
                    double priceDouble = Double.parseDouble(price);
                    String newPrice = df.format(priceDouble * 0.9);
                    
                    // 计算当前组数据的起始指针位置:当前指针减去4行内容总长度+4个换行符(按LF单字节计算)
                    long startPos = raf.getFilePointer() - (name.length() + floors.length() + price.length() + location.length() + 4);
                    raf.seek(startPos);
                    // 写入修改后的数据,保持换行分隔
                    raf.writeBytes(name + "\n" + floorsInt + "\n" + newPrice + "\n" + location + "\n");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键修复点

  • 读取逻辑修正:连续读取4行作为一组数据,直接赋值给对应变量,完全不需要split操作。
  • 空值校验:处理前检查4行数据是否完整,避免文件末尾数据缺失导致的异常。
  • 指针位置校准:修改数据时准确计算当前组的起始位置,确保覆盖正确的内容;注意换行符字节数(Windows系统是\r\n占2字节,若你的文件是该格式,需把+4改为+8)。
  • 空指针防护:用"1".equals(floors)代替floors.equals("1"),避免floors为null时抛出空指针异常。

额外注意事项

  • writeBytes()会按ASCII编码写入字符串,若文本包含非ASCII特殊字符(比如波兰语字符),可能出现乱码,建议改用writeUTF()和readUTF(),但需注意文件格式兼容性。
  • 如果修改后的内容长度和原内容不一致,会覆盖后续的文件内容。比如原价格是1000000.00(9字符),打折后是900000.00(8字符),会残留一个字节的旧内容,这种情况建议先把所有内容读入内存修改后再整体写回。

内容的提问来源于stack exchange,提问作者Janek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:40:41