【问题标题】:Functionally parsing/assembling a file功能解析/组装文件
【发布时间】:2018-03-30 17:16:20
【问题描述】:

我有一个要解析的 sql 文件。我可以轻松加载整个文件 string.split(";") 并正确分隔文件。但是,从挑战和学习的角度来看,我想应用一些功能 foo 和一些流来处理任意大小的文件。但这会变得很棘手。

基本上我需要:

  1. 加载任意数据缓冲区(假设是一行,因为我可以使用 Java 的 BufferedReader 流式传输这些
  2. 继续连接这些行直到有分隔符;
  3. 发出连接的结果
  4. 在分隔符后开始新的 sql 命令
  5. 最终结果:List<String>代表所有要执行的sql命令

这是一个示例:

CREATE SCHEMA HelloWorld;

USE HelloWorld;

CREATE TABLE HelloWorldTest (
  id int PRIMARY KEY NOT NULL AUTO_INCREMENT,
  message VARCHAR(32)
);

INSERT INTO HelloWorldTest (message) VALUES ('Hello world!');
INSERT INTO HelloWorldTest (message) VALUES ('this is a test!');

Java 效率低下:

 String fileData = IOUtils.toString(sqlFile);
 List<String> sqlStats = stream(fileData.split(";")).filter(s -> s.length() > 0)
        .collect(toList());

如何使用流和函数式编程来处理任何大小的文件?欢迎使用非 Java 的答案,因为 Java 可能无法使用本机库完成这项工作

【问题讨论】:

  • 请解释为什么效率低下。此外,您可以使用 String#isEmpty 代替 s.length() &gt; 0
  • @VinceEmigh 我当然可以使用!s.isEmpty()。假设 SQL 文件为 400mb 或 400gb - 将整个内容加载到内存中以解析它具有垂直缩放限制
  • 我在问如何这效率低下?您显然不会一次将 400gb 存储在内存中——这不切实际。 为什么您需要一次在内存中存储所有数据?在给定时间加载并解析您需要的内容。这听起来像XY problem,应该可以解释为什么您需要一个可以一次解析 400gb 的系统,因为它可能不需要。解释你的实际问题,而不是你的解决方案的问题(需要一次加载和解析 400gb 的数据)
  • this answer的结尾;当它确实必须是流时转换为流,您可以考虑the answer you already gotthis answer...

标签: java functional-programming stream java-stream


【解决方案1】:

使用扫描仪:

try (Scanner s = new Scanner(new File("/path/to/file.txt"))) {
    s.useDelimiter(";");
    Spliterator<String> splt = Spliterators.spliterator(s, Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.NONNULL);
    StreamSupport.stream(splt, false).filter(x -> !x.isEmpty()).forEach(executeSql);
}

【讨论】:

  • .filter(String::isEmpty)接受空字符串;你肯定想要相反的,.filter(str-&gt; !str.isEmpty())。此外,接收现有Scanner 作为参数的方法不应处理关闭扫描仪,这是调用者的责任。除此之外,它可以完成工作,但您可以简化,例如只需使用s.useDelimiter(";");。请注意,在 Java 9 中,您可以使用 s.useDelimiter(";").tokens() .filter(str -&gt; !str.isEmpty()).forEach(…) 来做同样的事情。
  • @Holger 你所说的一切都是绝对正确的。我会更正代码。
  • @Holger 不完全是我的想法,但比我正在做的要好得多。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 2015-11-21
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
相关资源
最近更新 更多