简体   繁体   English

如何在Java的jtextArea中附加50 mb数据(来自文本文件)?

[英]How to append 50 mb data(From text file) in jtextArea in java?

I have a big file which is having 50 mb data.I want to read and append into jTextArea(). 我有一个大文件,有50​​ mb的数据。我想读取并追加到jTextArea()中。 But i am getting out of * memory error * while appending data.How can i do this?please anyone help me 但是我在附加数据时遇到* 内存错误 *请问有人可以帮我吗?

example: 例:

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();

Either you can increase the maximum heap size, or you can use the paginator design pattern. 您可以增加最大堆大小,也可以使用分页器设计模式。

Pagination works by loading only those data that are actually visible. 分页通过仅加载那些实际可见的数据来工作。 So if your text area can display two pages of text, you load only those two displayed pages of text at a time. 因此,如果您的文本区域可以显示两页文本,则一次只能加载这两个显示的文本页。 If the user scrolls down, you throw away loaded pages and load those new two. 如果用户向下滚动,则丢弃已加载的页面,然后加载这两个页面。 That way, you will always have only two pages in memory at a time. 这样一来,您一次将始终只有两个页面在内存中。

尝试设置JVM的最大大小

I doubt there will ever be a user to read the 50MB of text that you would add to your JTextArea . 我怀疑是否会有用户阅读您将添加到JTextArea的50MB文本。

I suggest you implement some sort of pagination and only add a few 100s or 1000s of lines at once. 我建议您实现某种分页,一次只添加几百或几千行。

However, if you really want to add all the text then set the -Xmx parameter of your application to something higher. 但是,如果您确实要添加所有文本,则将应用程序的-Xmx参数设置为更高的值。

Ignoring that it is impractical in terms of usability (and JTextArea will probably not perform well with that much text), you can make some changes to your code to reduce the amount of memory needed (You probably still need to increase -Xmx). 忽略可用性方面的不切实际的考虑(JTextArea可能无法很好地处理这么多文本),您可以对代码进行一些更改以减少所需的内存量(您可能仍然需要增加-Xmx)。

Your first lever is to properly size the StringBuilder for the amount of data you want to put into it. 您的第一个方法是根据要放入其中的数据量适当调整StringBuilder的大小。 Replacing the new StringBuilder() with new StringBuilder(sizeOfFile) will avoid allocating more memory than needed (this may make a difference of several MB, due to StringBuilders internal memory allocation policy method). 新的StringBuilder(sizeOfFile)替换新的StringBuilder()将避免分配超出所需内存的内存(由于StringBuilders内部内存分配策略方法的原因,这可能会有几MB的差异)。

Now when you do builder.toString() , you should be aware that this will double the amount of memory required, since everything in the builder is copied to create the String. 现在,当您执行builder.toString()时 ,您应该意识到这将使所需的内存量增加一倍 ,因为会复制生成器中的所有内容以创建String。 With the normal Swing API, there is no way around that, since you absolutely need a String. 使用普通的Swing API,就没有解决办法,因为您绝对需要一个String。

But you can change that - look at how the JTextArea works internally: the JTextArea does not really store the text it works with - storing of the text is delegated to a model object, in this case of type javax.swing.Document. 但是您可以更改它-查看JTextArea在内部的工作方式:JTextArea并未真正存储其处理的文本-文本的存储委托给模型对象,在这种情况下,类型为javax.swing.Document。 If you take a look at Document, you'll find that its an interface. 如果您看一下Document,就会发现它是一个接口。 Normally when you use a JTextArea, it creates its own, private document which is not really intended for such large amounts of data (javax.swing.PlainDocument). 通常,当您使用JTextArea时,它会创建自己的私有文档,而该文档并不真正适用于如此大量的数据(javax.swing.PlainDocument)。 Now the PlainDocument in turn works with a javax.swing.Content (again an interface), normally implemented in javax.swing.StringContent. 现在,PlainDocument又可以使用javax.swing.Content(再次通过接口)工作,通常在javax.swing.StringContent中实现。 This you can replace with your own, new content class that works with a StringBuilder directly (that way there would be no need to duplicate data in memory). 您可以将其替换为自己的新内容类,该内容类直接与StringBuilder一起使用(这样,就无需在内存中重复数据)。

So, you can implement your own Content class working with StringBuilder and construct your JTextArea this way: 因此,您可以使用StringBuilder来实现自己的Content类,并通过以下方式构造JTextArea:

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

Actually creating and implementing StringBuilderContent is left as an excercise to the reader. 实际创建和实现StringBuilderContent留给读者练习。 Actually, you could also implement Content to directly work with a file, that way you could handle files much larger than available heap, too. 实际上,您也可以实现Content来直接处理文件,这样您就可以处理比可用堆大得多的文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM