假设我的文件为2GB,我希望从其中获取一些特定数据。索引到另一个索引(考虑到两个索引之间的特定数据300MB),这样做的更好方法是什么?我尝试了子字符串,但是抛出了内存不足异常。请提出更好的方法。
答案 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的子字符串,工作速度相当快。