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的使用逻辑错误:
- 给Scanner设置了
useDelimiter(",")后又调用nextLine(),会导致每次读取一整行,分隔符设置被忽略,而且拼接时会把下一行的开头直接连到上一行的结尾(比如第一行的0和第二行的Event拼成0Event),这就是异常结果的来源。 - 后续
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
相关产品推荐
相关产品推荐

