我有以下代码片段将文本文件的全部内容读入字符串。它有效,唯一的问题是......它真的很慢(文件长约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();
目前,我正在一次读取一行中的完整文件,然后将其附加到字符串中。有更快的方法吗?我正在寻找一种快速的方法将整个文件放入字符串中。
答案 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助手,但它通常更冗长)
除非你有理由避免第三方库?