Java Android 快速读取完整文件

4

我有以下代码片段,用于将文本文件的全部内容读入字符串。它可以工作,唯一的问题是...它非常慢(文件大约有1500行)。

            InputStream is = this.getResources().openRawResource(R.raw.comp_rules_glossary);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String previousLine = "start";

            while ((readLine = br.readLine()) != null)
            {
                rules = rules + readLine + eol;
                if (previousLine.equals(""))
                {
                    content = content + readLine + eol;
                }
                previousLine = readLine;
            }

            is.close();
            br.close();

目前,我正在一行一行地读取完整的文件,然后将其附加到字符串中。有没有更快的方法来完成这个过程?我正在寻找一种快速的方法来将整个文件读入一个字符串中。


1
请参考此链接:https://dev59.com/qnRC5IYBdhLWcg3wVvnL - Kevin Qiu
开个玩笑,看看我的解决方案。 - numegil
3个回答

3
使用 StringBuilder 构建大的字符串。
StringBuilder sb_rules = new StringBuilder();
StringBuilder sb_content = new StringBuilder();
while ((readLine = br.readLine()) != null)
{
    sb_rules.append(readLine);
    sb_rules.append(eol);
    if (previousLine.equals(""))
    {
        sb_content.append(readLine);
        sb_content.append(eol);
    }
    previousLine = readLine;
}
content = sb_rules.toString();
content = sb_content.toString();

为什么要使用StringBuilder而不是String?

String不允许追加。你在一个String上调用的每个方法都会创建一个新对象并返回它。这是因为String是不可变的 - 它不能改变其内部状态。


1

假设 Apache Commons 在 Android 上运行正常,你可以使用类似这样的东西吗?

InputStream is = this.getResources().openRawResource(R.raw.comp_rules_glossary);
String text = IOUtils.toString(is, "UTF-8");

(或者你可以使用Guava及其CharStreams帮助程序,但通常较冗长)

除非您有避免使用第三方库的原因?


1
在这种情况下,只写10行代码可能更好,而不是包含库。 代码足够简单,然后您可以避免将lib jar的额外大小添加到apk中,使其对移动用户尽可能小。 - user605331

1

我看到你似乎已经有了一个基于Kevin评论的工作解决方案,但了解为什么你的旧代码很慢可能会有所帮助。

问题在于,当你直接使用+运算符或concat()方法连接字符串时,它实际上是创建一个新的字符串,其中包含连接的结果。这涉及将你要连接的两个字符串的整个内容复制一遍。因此,当你读取文件并构建内容字符串时,每次添加内容时,你都会创建另一个包含到目前为止所有内容的副本。

解决方案,我假设你现在正在使用的是StringBuffer类,它是一个动态缓冲区,允许你修改其内容(即向末尾追加新数据),而不必总是分配一个新的String对象并将所有内容复制到它。

你必须记住的主要事情是,在Java中,字符串是不可变的。任何时候你调用一个改变它的Java字符串方法,它实际上是创建一个新的字符串副本,其中包含修改的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接