Java Android快速阅读完整文件

时间:2011-09-15 02:29:56

标签: java android performance file bufferedreader

我有以下代码片段将文本文件的全部内容读入字符串。它有效,唯一的问题是......它真的很慢(文件长约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();

目前,我正在一次读取一行中的完整文件,然后将其附加到字符串中。有更快的方法吗?我正在寻找一种快速的方法将整个文件放入字符串中。

3 个答案:

答案 0 :(得分: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();

Why StringBuilder when there is String?

  

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

答案 1 :(得分:1)

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

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

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

你必须记住的主要事情是java中的字符串是不可变的。每当你在java String上调用一个以某种方式改变它的方法时,它实际上是在创建一个带有修改结果的字符串的新副本。

答案 2 :(得分:1)

假设Apache Commons在Android上工作正常,你可以使用这样的东西吗?

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

(或者你可以使用Guava及其CharStreams助手,但它通常更冗长)

除非你有理由避免第三方库?