如何在java的jtextArea中追加50MB的数据(来自文本文件)?

如何在java的jtextArea中追加50MB的数据(来自文本文件)?,java,swing,jtextarea,Java,Swing,Jtextarea,我有一个大文件,有50 mb的数据。我想读取并附加到jTextArea()。但我在追加数据时内存不足错误*。我该怎么做?请任何人帮助我 例如: BufferedReader br; StringBuilder builder = new StringBuilder(); try { br = new BufferedReader(new FileReader("D:\\myFile.txt")); String li

我有一个大文件,有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();

尝试设置JVM的最大大小

尝试设置JVM的最大大小

我怀疑是否会有用户阅读您将添加到
JTextArea
的50MB文本

我建议您实现某种分页,一次只添加几个100或1000行


但是,如果您真的想添加所有文本,请将应用程序的
-Xmx
参数设置为更高的值。

我怀疑是否会有用户阅读您将添加到
JTextArea
的50MB文本

我建议您实现某种分页,一次只添加几个100或1000行


但是,如果确实要添加所有文本,请将应用程序的
-Xmx
参数设置为更高的值。

可以增加最大堆大小,也可以使用分页器设计模式


分页的工作原理是只加载那些实际可见的数据。因此,如果您的文本区域可以显示两页文本,则一次只能加载这两页文本。如果用户向下滚动,您将丢弃加载的页面并加载这两个新页面。这样,一次内存中始终只有两页。

您可以增加最大堆大小,也可以使用分页器设计模式


分页的工作原理是只加载那些实际可见的数据。因此,如果您的文本区域可以显示两页文本,则一次只能加载这两页文本。如果用户向下滚动,您将丢弃加载的页面并加载这两个新页面。这样,一次内存中始终只有两页。

忽略这在可用性方面是不切实际的(而且JTextArea可能无法处理这么多的文本),您可以对代码进行一些更改以减少所需的内存量(您可能仍然需要增加-Xmx)

您的第一个杠杆是根据您想要输入的数据量适当调整StringBuilder的大小。用新的StringBuilder(sizeOfFile)替换新的StringBuilder()将避免分配超过所需的内存(由于StringBuilder内部内存分配策略方法,这可能会产生几MB的差异)

现在,当您执行builder.toString()时,您应该知道这将使所需的内存量增加一倍,因为将复制builder中的所有内容来创建字符串。对于普通的Swing API,没有办法解决这个问题,因为您绝对需要一个字符串

但是您可以改变这一点——看看JTextArea在内部是如何工作的:JTextArea并不真正存储它所使用的文本——文本的存储被委托给一个模型对象,在本例中是javax.swing.Document类型。若你们看一下这个文档,你们会发现它是一个接口。通常,当您使用JTextArea时,它会创建自己的私有文档,而该文档实际上并不适用于如此大量的数据(javax.swing.PlainDocument)。现在,PlainDocument反过来与javax.swing.Content(又是一个接口)一起工作,通常在javax.swing.StringContent中实现。您可以将其替换为您自己的、直接与StringBuilder一起工作的新内容类(这样就不需要在内存中复制数据)

因此,您可以使用StringBuilder实现自己的内容类,并通过以下方式构造JTextArea:

Content c = new StringBuilderContent(builder);
Document d = new PlainDocument(c);
JTextArea jt = new JTextArea(d);

实际上,创建和实现StringBuilderContent是留给读者的练习。实际上,您也可以实现内容来直接处理文件,这样您也可以处理比可用堆大得多的文件。

忽略这在可用性方面是不切实际的(而且JTextArea可能无法处理这么多的文本),您可以对代码进行一些更改以减少所需的内存量(您可能仍然需要增加-Xmx)

第一个杠杆是根据要放入的数据量适当调整StringBuilder的大小。使用新StringBuilder(sizeOfFile)替换新StringBuilder()将避免分配超过所需的内存(由于StringBuilder内部内存分配策略方法的不同,这可能会产生几MB的差异)

现在,当您执行builder.toString()时,您应该知道这将使所需的内存量增加一倍,因为生成器中的所有内容都是复制来创建字符串的。使用普通的Swing API,无法解决这一问题,因为您绝对需要一个字符串

但是你可以改变这种情况——看看JTextArea内部是如何工作的:JTextArea并不真正存储它所使用的文本——文本的存储被委托给一个模型对象,在这种情况下是javax.swing.Document类型。如果你看一看文档,你会发现它是一个接口。通常当你使用JTextArea时,它会创建自己的接口,私有文档,该文档实际上不适用于如此大量的数据(javax.swing.PlainDocument)。现在,PlainDocument反过来与javax.swing.Content(又是一个接口)一起工作,通常在javax.swing.StringContent中实现。您可以用自己的、直接与StringBuilder一起工作的新内容类来替换它(这样就不需要在内存中复制数据)

因此,您可以使用StringBuilder实现自己的内容类,并通过以下方式构造JTextArea:

Content c = new StringBuilderContent(builder);
Document d = new PlainDocument(c);
JTextArea jt = new JTextArea(d);

实际上,创建和实现StringBuilderContent是留给读者的练习。实际上,您也可以实现内容来直接处理文件,这样您也可以处理比可用堆大得多的文件。

50MB的原始文本就像35本圣经!为什么一个字段中需要这么多文本?阅读