我有一个大文件,有50 MB的数据。我想阅读并附加到jTextArea()。但是我在附加数据的时候出现内存错误 * 。我怎么能这样做?请有人帮助我
示例:
BufferedReader br;
StringBuilder builder = new StringBuilder();
try {
br = new BufferedReader(new FileReader("D:\\myFile.txt"));
String line;
try {
while ((line = br.readLine()) != null) {
// process the line.
builder.append(line);// here getting error
}
System.out.println(builder.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JTextArea jt = new JtextArea();
jt.append(builder.toString();
答案 0 :(得分:2)
您可以增加最大堆大小,也可以使用分页器设计模式。
分页的工作原理是只加载实际可见的数据。因此,如果您的文本区域可以显示两页文本,则一次只加载这两个显示的文本页面。如果用户向下滚动,则会丢弃已加载的页面并加载这两个新页面。这样,您一次只能在内存中有两个页面。
答案 1 :(得分:1)
尝试设置JVM的最大大小
答案 2 :(得分:1)
我怀疑用户是否会阅读您要添加到JTextArea
的50MB文字。
我建议您实施某种分页,一次只添加几百或一千行。
但是,如果您确实要添加所有文本,请将应用程序的-Xmx
参数设置为更高的值。
答案 3 :(得分:0)
忽略它在可用性方面是不切实际的(并且JTextArea可能在这么多文本中表现不佳),您可以对代码进行一些更改以减少所需的内存量(您可能仍需要增加-Xmx )。
您的第一个杠杆是正确调整StringBuilder的大小,以获得您想要放入其中的数据量。用 new StringBuilder(sizeOfFile)替换 new StringBuilder()将避免分配比所需更多的内存(由于StringBuilders内部内存分配策略,这可能会产生几MB的差异法)。
现在当您执行 builder.toString()时,您应该知道这将加倍所需的内存量,因为构建器中的所有内容都是复制以创建String。使用普通的Swing API,没有办法解决这个问题,因为你绝对需要一个字符串。
但是你可以改变它 - 看看JTextArea如何在内部工作:JTextArea并不真正存储它使用的文本 - 文本的存储被委托给模型对象,在这种情况下类型为javax.swing.Document 。如果你看看Document,你会发现它是一个界面。通常,当您使用JTextArea时,它会创建自己的私有文档,该文档并非真正用于大量数据(javax.swing.PlainDocument)。现在,PlainDocument依次使用javax.swing.Content(同样是一个接口),通常在javax.swing.StringContent中实现。这可以替换为您自己的直接与StringBuilder一起使用的新内容类(这样就不需要在内存中复制数据了。)
因此,您可以使用StringBuilder实现自己的Content类,并以这种方式构建JTextArea:
Content c = new StringBuilderContent(builder);
Document d = new PlainDocument(c);
JTextArea jt = new JTextArea(d);
实际上,创建和实现StringBuilderContent是留给读者的练习。实际上,您还可以实现内容以直接使用文件,这样您就可以处理比可用堆大得多的文件。