对大文本进行子字符串化的更好方法是什么?

时间:2019-01-17 05:22:05

标签: java string file substring file-read

假设我的文件为2GB,我希望从其中获取一些特定数据。索引到另一个索引(考虑到两个索引之间的特定数据300MB),这样做的更好方法是什么?我尝试了子字符串,但是抛出了内存不足异常。请提出更好的方法。

2 个答案:

答案 0 :(得分:3)

通常,假设磁盘上有2GB的文件,并且您想将其中的一部分读取到内存中,则绝对不必先将整个2GB的内容读取到内存中。

最直接的解决方案是使用Random Access File

重点是它提供了一个指针的抽象,可以在一个大文件中来回移动,一旦设置,就可以从指针指向的位置读取字节。

RandomAccessFile file = new RandomAccessFile(path, "r");
file.seek(position);
byte[] bytes = new byte[size];
file.read(bytes);
file.close();

答案 1 :(得分:0)

按字符读取文件并将它们写入输出文件可以解决此问题。因为它不会一次加载整个文件。

因此,该过程将是-按字符读取输入文件,继续到所需的子字符串开始索引,然后开始写入输出文件,直到子字符串结束。

如果您获得Exception in thread "main" java.lang.OutOfMemoryError: Java heap space,如果确实需要一次读取文件并且可以确定String大小不会超过最大String大小限制,则可以尝试增加堆大小。

以下代码片段显示了上述想法-

import java.io.*;

public class LargeFileSubstr {

    public static void main(String[] args) throws IOException {
        BufferedReader r = new BufferedReader(new FileReader("/Users/me/Downloads/big.txt"));

        try (PrintWriter wr = new PrintWriter(new FileWriter("/Users/me/Downloads/big_substr.txt"))) {
            int startIndex = 100;
            int endIndex = 200;
            int pointer = 0;
            int ch;

            while ((ch = r.read()) != -1) {

                if (pointer > endIndex) {
                    break;
                }

                if (pointer >= startIndex) {
                    wr.print((char) ch);
                }

                pointer++;

            }
        }

    }
}

我已经尝试过从2GB的文件中取出200MB的子字符串,工作速度相当快。