【发布时间】:2018-03-30 17:16:20
【问题描述】:
我有一个要解析的 sql 文件。我可以轻松加载整个文件 string.split(";") 并正确分隔文件。但是,从挑战和学习的角度来看,我想应用一些功能 foo 和一些流来处理任意大小的文件。但这会变得很棘手。
基本上我需要:
- 加载任意数据缓冲区(假设是一行,因为我可以使用
Java 的
BufferedReader流式传输这些 - 继续连接这些行直到有分隔符
; - 发出连接的结果
- 在分隔符后开始新的 sql 命令
- 最终结果:
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() > 0 -
@VinceEmigh 我当然可以使用
!s.isEmpty()。假设 SQL 文件为 400mb 或 400gb - 将整个内容加载到内存中以解析它具有垂直缩放限制 -
我在问如何这效率低下?您显然不会一次将 400gb 存储在内存中——这不切实际。 为什么您需要一次在内存中存储所有数据?在给定时间加载并解析您需要的内容。这听起来像XY problem,应该可以解释为什么您需要一个可以一次解析 400gb 的系统,因为它可能不需要。解释你的实际问题,而不是你的解决方案的问题(需要一次加载和解析 400gb 的数据)
-
见this answer的结尾;当它确实必须是流时转换为流,您可以考虑the answer you already got 或this answer...
标签: java functional-programming stream java-stream