在Java中解析制表符分隔的文件最原始的方法是什么,这样表格数据就不会丢失结构?我不寻找一种使用 Bean 或 Jsoup 来完成此操作的方法,因为我这个初学者对它们不熟悉。我需要关于其背后的逻辑是什么以及有效的方法是什么的建议,例如,如果我有一个像
这样的表ID reference | Identifier | Type 1| Type 2 | Type 3 |
1 | red#01 | 15% | 20% | 10% |
2 | yellow#08 | 13% | 20% | 10% |
更正:在此示例中,我有类型 1 - 3,但我的问题适用于 N 种类型。
我可以仅使用数组来实现表解析吗?Java 中是否有其他数据结构更适合此任务?我认为我应该这样做:
- 扫描/读取在
"\t"
处分割的第一行并创建一个字符串数组。 - 将该数组拆分为子数组,每个子数组有 1 个表标题
- 然后,开始读取表格的下一行,并为每个子数组添加列中相应的值。
这个计划听起来正确还是我让事情变得过于复杂/完全错误?有更简单的方法吗? (前提是我仍然不知道如何将数组拆分为子数组以及如何使用表中的值填充子数组)
最佳答案
我强烈建议您为此使用读取平面文件解析库,例如优秀的 OpenCSV .
如果做不到这一点,这里有一个 Java 8 中的解决方案。
首先,创建一个类来表示您的数据:
static class Bean {
private final int id;
private final String name;
private final List<Integer> types;
public Bean(int id, String name, List<Integer> types) {
this.id = id;
this.name = name;
this.types = types;
}
//getters
}
您使用各种列表的建议非常基于脚本。 Java 是面向对象的,因此您应该利用它来发挥自己的优势。
现在我们只需要解析文件:
public static void main(final String[] args) throws Exception {
final Path path = Paths.get("path", "to", "file.tsv");
final List<Bean> parsed;
try (final Stream<String> lines = Files.lines(path)) {
parsed = lines.skip(1).map(line -> line.split("\\s*\\|\\s*")).map(line -> {
final int id = Integer.parseInt(line[0]);
final String name = line[1];
final List<Integer> types = Arrays.stream(line).
skip(2).map(t -> Integer.parseInt(t.replaceAll("\\D", ""))).
collect(Collectors.toList());
return new Bean(id, name, types);
}).collect(Collectors.toList());
}
}
本质上,代码会跳过第一行,然后循环遍历文件中的行和每一行:
- 在分隔符上拆分行 - 似乎是
|
。这需要正则表达式,因此您需要转义管道,因为它是一个特殊字符。我们还会消耗分隔符之前/之后的所有空格。 - 创建
new Bean
通过解析数组元素来获取每一行。 - 首先将 id 解析为
int
- 接下来获取名称
- 终于得到
Stream
行中,跳过前两个元素,并将其余元素解析为List<Integer>
关于java - 解析制表符分隔文件的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22585187/