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

Java拆分文本文件内容时,如何避免行尾与下一行内容拼接?

问题描述

我有一个内容如下的.txt文件:

Event=ThermostatNight,time=0
Event=LightOn,time=2000
Event=WaterOff,time=10000
Event=ThermostatDay,time=12000
Event=Bell,time=9000,rings=5
Event=WaterOn,time=6000
Event=LightOff,time=4000
Event=Terminate,time=20000
Event=FansOn,time=7000
Event=FansOff,time=8000

我希望将上述内容存入数组,预期数组格式如下:

[0] = Event
[1] = ThermostatNight
[2] = time
[3] = 0
[4] = Event
[5] = LightOn
[6] = time
[7] = 2000
//.... etc

本质上我想将事件名和时间分别存为变量,使用=和,作为拆分符,但实际拆分后索引[3]显示为"0Event"、索引[6]显示为"2000Event"等问题。

我尝试了以下代码:

public static void main(String[] args) {
    try {
        Scanner content = new Scanner(new File("file.txt")).useDelimiter(",");
        StringBuilder sb = new StringBuilder();
        while(content.hasNext()) {
            sb.append(content.nextLine());
        }
        String[] wordsArray = sb.toString().split("[=,]");
        //Test what is at each index
        System.out.println(wordsArray[3]);          
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

还修改过split的参数,比如:

.split("\[=,\\n\]")
.split("\[=,\\s\]")
.split("\[=,\\n\]")
...etc

但仍然出现索引[3]和[6]为0Event、2000Event的问题,不确定是思路错误还是方法不对,求帮助。

问题分析与解决方案

问题根源在Scanner的使用逻辑错误:

  1. 给Scanner设置了useDelimiter(",")后又调用nextLine(),会导致每次读取一整行,分隔符设置被忽略,而且拼接时会把下一行的开头直接连到上一行的结尾(比如第一行的0和第二行的Event拼成0Event),这就是异常结果的来源。
  2. 后续split未处理换行符,无法拆分粘连的内容。

修正方案一:逐行处理再合并

逐行读取文件,对每一行单独拆分后合并到结果集合中,逻辑清晰且不易出错:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(new File("file.txt"));
            List<String> resultList = new ArrayList<>();
            
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();
                // 按=或,拆分当前行,正则[]表示匹配其中任意一个字符
                String[] lineParts = line.split("[=,]");
                for (String part : lineParts) {
                    resultList.add(part.trim()); // 去除冗余空格,提升健壮性
                }
            }
            
            // 转换为目标数组
            String[] wordsArray = resultList.toArray(new String[0]);
            
            // 测试输出前8个元素
            for (int i = 0; i < 8; i++) {
                System.out.printf("[%d] = %s%n", i, wordsArray[i]);
            }
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行后将得到预期的数组格式:

[0] = Event
[1] = ThermostatNight
[2] = time
[3] = 0
[4] = Event
[5] = LightOn
[6] = time
[7] = 2000

修正方案二:一次性读取后全局拆分

若想一次性处理所有内容,需将换行符加入拆分规则,同时过滤空字符串:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try {
            // 一次性读取全部文件内容(\\Z表示输入流末尾)
            Scanner scanner = new Scanner(new File("file.txt")).useDelimiter("\\Z");
            String allContent = scanner.next();
            
            // 拆分规则:匹配=、,或换行符(\r?\n兼容Windows/Linux换行格式)
            String[] rawParts = allContent.split("[=,\\r?\\n]");
            
            // 过滤空字符串(避免文件首尾换行产生的无效元素)
            List<String> filteredParts = new ArrayList<>();
            for (String part : rawParts) {
                String trimmed = part.trim();
                if (!trimmed.isEmpty()) {
                    filteredParts.add(trimmed);
                }
            }
            String[] wordsArray = filteredParts.toArray(new String[0]);
            
            // 测试关键索引
            System.out.println(wordsArray[3]); // 输出0
            System.out.println(wordsArray[6]); // 输出2000
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

额外优化建议

如果最终目的是存储事件的各类属性,用对象或Map替代数组会更易维护:

// 定义事件类
class Event {
    String type;
    int time;
    Integer rings; // 可选字段,用Integer支持null

    public Event(String type, int time, Integer rings) {
        this.type = type;
        this.time = time;
        this.rings = rings;
    }
}

处理时将每行解析为Event对象存入List<Event>,后续取值、操作都会更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:07:33