Java 正在读取一个大文件

Java reading a big file

所以我的想法是我有这个 .json 文件需要阅读。 它太大了,我什至无法使用记事本或 Visual studio 代码打开它。

我试过这个:

BufferedReader in = new BufferedReader(new FileReader("path to the file"));
String line = in.readLine();

我得到这个错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.base/java.util.Arrays.copyOf(Arrays.java:3536) at java.base/java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:228) at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:735) at java.base/java.lang.StringBuilder.append(StringBuilder.java:227) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:372) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) at com.ReadJSON.TagValues.listFilesForFolder(TagValues.java:133) at com.ReadJSON.TagValues.listFilesForFolder(TagValues.java:129) at com.ReadJSON.TagValues.listFilesForFolder(TagValues.java:129) at com.ReadJSON.TagValues.listFilesForFolder(TagValues.java:129) at com.ReadJSON.Main.main(Main.java:18)

我在互联网上搜索了一些解决方案是更改内存设置,但它不起作用,它 returns 同样的错误。 另一个问题是整个文件是ONELINE。文件的全部内容写在一行中。 我想我必须在某个时间中断该行的读取部分,这样它就不会超过分配的最大内存,存储该值并从我离开的地方再次开始读取。一遍又一遍地这样做,直到行尾。

关于我应该如何阅读这个文件有什么建议吗?我应该尝试不同的方式来阅读它还是有什么技巧可以打破 readLine()?

谢谢!

即使您可以增加 JVM 内存限制,但这是不必要的,并且分配像 1GB 这样的巨大内存来处理文件过度杀伤和资源密集型。

InputStream inFileReader = channelSFtp.get(path); // file reading from ssh.
byte[] localbuffer = new byte[2048];

int i = 0;
while (-1 != (i = inFileReader.read(buffer))) {
    //Deal with the current read 2KB file chunk here
}

inFileReader.close();

这样你就可以一段一段地看下去了

对于如此巨大的 JSON 文件,不应将整个 JSON DOM 文档对象模型读入内存。但是使用流解析器。

如果只有一大行,带有 readLine 的 BufferedReader 无论如何都是错误的。此外 JSON 文件通常采用 UT-8 编码。 FileReader 是使用默认字符编码的旧实用程序 class:不可移植代码,错误。

有一个 Jackson Streaming API。对于使用 maven 的项目:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.3</version>
</dependency>

代码如下:

JsonFactory factory = new JsonFactory();
try (JsonParser parser = jactory.createParser(...)) {
    while (parser.nextToken() != JsonToken.END_OBJECT) {
        String field = parser.getCurrentName();
        switch (field) {
        case "...":
            ...
            ... parser.getText();
            ... parser.getIntValue();
            break;
    }
}

用于提取部分数据,或将数据存储在数据库中。

您可以查看 DSM 流媒体库。您可以在解析文档的同时处理 JSON 文档。您在 yaml 中为要处理的数据定义映射。它根据映射文件处理 JSON 文档。 DSM 使用 Jackson 流 api.

你可以查看这个问题中的例子

JAVA - Best approach to parse huge (extra large) JSON file