如何在 Swing 中读取和显示大文本文件?
Posted
技术标签:
【中文标题】如何在 Swing 中读取和显示大文本文件?【英文标题】:How to read and display large text files in Swing? 【发布时间】:2014-09-22 19:04:05 【问题描述】:这听起来可能有点复杂,我会尽量简化我的要求。
我正在开发的程序可以使用JTextArea
读写文件。当文件相当大时,将数据从该文件读取到文本区域确实需要大量时间。例如,我有一个文件,目前有 40,000 行文本,每行大约 50 个字符;此外,有些行会换行。有很多文本,从该文件中读取所需的时间比我想要的要多得多。
目前,我正在使用标准读取方法,该方法利用了JTextArea
组件包含的BufferedReader
实例。我想做的是加载JTextArea
,并在屏幕上加载一定数量的文本。屏幕外的其余文本在后台的单独线程中加载。
使用InputStream
并将每个字符写入数组然后将字符写入JTextArea
就足够了吗?还是应该有不同的方法?我正在尝试实现一种快速高效的读取方法。
【问题讨论】:
(FWIW:2MB 的文件对于今天的硬件来说不是很“大”——也就是说,它运行速度是否太慢?对于真正的大文件,有更好的方法。) 嗯,它实际上有 4.20 mb 大,但我同意。但是,加载时间仍然比我喜欢的要长。 使用 BufferedReader(包装 InputStream),顺序 IO 应该“几乎是即时的”。对加载 (IO) 和加载 (UI) 计时,看看哪个引入了不希望的延迟。 好吧,我明白了。我目前正在使用带有包装器 FileReader 的 BufferedReader。那么 InputStream 会更高效吗? 几乎可以肯定,问题不在于读取文件,而在于试图让 JTextArea 处理数据。您可以进行某种手动分页,只将数据的某个子集设置到 jtextarea 中。 【参考方案1】:手头有两个直接的问题
首先,需要读取一个文件,以便它可以逐步更新 UI 而不会导致不可接受的延迟
其次,JTextArea
实际处理这些数据量的能力...
第一个问题相对来说比较容易解决。您需要确保的是,您在读取文件时没有阻塞事件分派线程,并且您只是在事件分派线程的上下文中更新JTextArea
。为此,SwingWorker
是一个很好的选择,例如...
public class FileReaderWorker extends SwingWorker<List<String>, String>
private File file;
private JTextArea ta;
public FileReaderWorker(File file, JTextArea ta)
this.file = file;
this.ta = ta;
public File getFile()
return file;
public JTextArea getTextArea()
return ta;
@Override
protected List<String> doInBackground() throws Exception
List<String> contents = new ArrayList<>(256);
try (BufferedReader br = new BufferedReader(new FileReader(getFile())))
String text = null;
while ((text = br.readLine()) != null)
// You will want to deal with adding back in the new line characters
// here if that is important to you...
contents.add(text);
publish(text);
return contents;
@Override
protected void done()
try
get();
catch (InterruptedException | ExecutionException ex)
ex.printStackTrace();
// Handle exception here...
@Override
protected void process(List<String> chunks)
JTextArea ta = getTextArea();
for (String text : chunks)
ta.append(text);
查看Concurrency in Swing 和Worker Threads and SwingWorker 了解更多详情
ps-你不需要使用List
来存储内容,我只是做了一个例子......
第二个问题要复杂得多,需要一些额外的测试来确保它确实是一个问题,但一般来说,超过 1mb 的内容往往会导致问题......
为此,您需要能够管理JScrollPane
,能够从文件中向后和向前请求文本块,并尝试有效地“捏造”该过程(这样您只能已经加载了您需要的文本,但仍然可以让它看起来像您已经在 JTextArea
) 中加载了所有文本...
您还可以查看FileChannel
,它提供了比标准java.io
类更多的功能,包括内存映射,对于初学者,请查看Reading, Writing, and Creating Files。
您还可以考虑使用为显示大量数据而高度优化的JList
或JTable
。这有一些限制,因为有固定行高的预期,当更改(动态行高)时会影响性能,但可能是一个合适的替代方案......
【讨论】:
我会尝试使用JList
或 JTable
作为视图,以利用享元渲染。
@trashgod 对于查看,绝对,如果 OP 期望能够编辑值,它会变得有点复杂,但并非不可能......
好点;默认的JTable
编辑器就足够了,但回写可能很乏味。
还有固定行高和动态行高的问题,固定行高的组件得到了很好的优化,动态行高意味着组件需要测试每一行才能计算出行高组件,如果认真做,更新可以做得很好,但是要牢记的一个考虑...以上是关于如何在 Swing 中读取和显示大文本文件?的主要内容,如果未能解决你的问题,请参考以下文章