gpt4 book ai didi

java - 使用java 8流解析多行记录

转载 作者:行者123 更新时间:2023-11-30 03:24:57 26 4
gpt4 key购买 nike

我正在尝试解析以下文件,其中包含以下格式的信息:

TABLE_NAME

VARIABLE_LIST_OF_COLUMNS

VARIABLE_NUMBER_OF_ROWS (Seperated by a tab seperator)

示例(使用“,”作为问题的分隔符;实际分隔符是制表符):

STUDENTS

ID

NAME

1,Mike

2,Kimberly

这个想法是构建一个插入 sql 语句的列表(代码片段的上下文)。

我想知道这种多行解析是否可以使用 java 8 Streams API 实现?这就是我现在所拥有的:

public final class StatementGeneratorMain {

public static void main(final String[] args) throws Exception{
List<String> fileNames = Arrays
.asList("STUDENTS.txt");
fileNames.stream()
.forEach(fileName -> {
String tableName;
List<String> columnNames;
List<String[]> dataRows;
try (BufferedReader br = getBufferedReader(fileName)) {
tableName = br.lines().findFirst().get();
} catch (Exception e) {
throw new RuntimeException(e);
}

try (BufferedReader br = getBufferedReader(fileName)) {
//skip the first line because its been processed.
columnNames = br.lines().skip(1).filter(v -> v.split("\t").length == 1).collect(toList());
} catch (Exception e) {
throw new RuntimeException(e);
}

try (BufferedReader br = getBufferedReader(fileName)) {
//skip the first line and the columns length to get the data
//columns are identified as being splittable on the delimiter
dataRows = br.lines().skip(1 + columnNames.size()).map(s -> s.split("\t"))
.collect(toList());
} catch (Exception e) {
throw new RuntimeException(e);
}

String columns = columnNames.stream().collect(joining(",","(",")"));

List<String> dataRow = dataRows.stream()
.map(arr -> Arrays.stream(arr).map(x -> "'" + x + "'").collect(joining(",", "(", ")")))
.map(row -> String.format("INSERT INTO %s %s VALUES %s;", tableName, columns, row))
.collect(toList());

dataRow.forEach(l -> System.out.println(l));
});
}

private static BufferedReader getBufferedReader(String fileName) {
return new BufferedReader(new InputStreamReader(StatementGeneratorMain.class.getClassLoader().getResourceAsStream(
fileName)));
}
}

这段代码为我完成了这项工作,但我真的不喜欢它,因为我三次读取同一个文件(一次用于表名,再次推导列,再次获取行)。我也不认为这是正确的函数式风格。

我正在寻找一种更优雅的方式来使用流 API 进行这种多行/多记录解析。

为了完整起见,输出为:

INSERT INTO STUDENTS (ID, NAME) VALUES ('1','Mike');

INSERT INTO STUDENTS (ID, NAME) VALUES ('2','Kimberly');

此时我对数字列和空值之类的东西不太挑剔。

最佳答案

我不确定在这里使用流是否是正确的方法,因为它们旨在用于迭代数据一次,或者更准确地说,以一种方式处理数据。如果您需要以不同的方式处理单独的数据 block ,您可能应该使用良好的旧循环或迭代器。我想到的最简单的解决方案之一是使用 Scanner,这样您的代码就可以如下所示:

Pattern oneWordLine = Pattern.compile("^\\w+$", Pattern.MULTILINE);

List<String> files = Arrays.asList("input.txt");
for (String file : files) {

try (Scanner sc = new Scanner(new File(file))) {

String tableName = sc.nextLine();

StringJoiner columnNamesJoiner = new StringJoiner(", ", "(", ")");
// iterate over lines with single words
while (sc.hasNext(oneWordLine)) {
columnNamesJoiner.add(sc.nextLine());
}
String columns = columnNamesJoiner.toString();


List<String> dataRow = new ArrayList<>();
// iterate over rest of lines
while (sc.hasNextLine()) {
String values = Arrays.stream(sc.nextLine().split("\t"))
.collect(joining("', '", "('", "')"));
dataRow.add(String.format("INSERT INTO %s %s VALUES %s;",
tableName,columns, values));
}

dataRow.forEach(System.out::println);

} catch (Exception e) {
e.printStackTrace();// no need to rethrow RuntimeEception
}
}

关于java - 使用java 8流解析多行记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30469304/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com