【问题标题】:Opening a 12kb text file takes WAY too long....?打开一个 12kb 的文本文件需要太长时间......?
【发布时间】:2010-12-01 21:45:56
【问题描述】:

以下代码有效,但打开一个小文件所需的时间太长(超过一分钟)。 LogCat 显示了很多“GC_FOR_MALLOC freed #### objects / ###### bytes in ##ms”的实例。有什么建议吗?

 File dirPath = new File(Environment.getExternalStorageDirectory(), "MyFolder");
 String content = getFile("test.txt");

 public String getFile(String file){
  String content = "";
  try {
   File dirPathFile = new File(dirPath, file);
   FileInputStream fis = new FileInputStream(dirPathFile);
   int c;
   while((c = fis.read()) != -1) {
    content += (char)c;
   }
   fis.close();
  } catch (Exception e) {
   getLog("Error (" + e.toString() + ") with: " + file);
  }
  return content;
 }

更新:

这就是现在的样子:

File dirPath = new File(Environment.getExternalStorageDirectory(), "MyFolder");
String content = getFile("test.txt");

public String getFile(String file){
    String content = "";
    File dirPathFile = new File(dirPath, file);
    try {
        StringBuilder text = new StringBuilder();
        BufferedReader br = new BufferedReader(new FileReader(dirPathFile));
        String line;
        while ((line = br.readLine()) != null) {
            text.append(line);
            text.append('\n');
        }
        content = new String(text);
        } catch (Exception e) {
            getLog("Error (" + e.toString() + ") with: " + file);
    }
    return content;
}

谢谢大家!!

【问题讨论】:

  • 我尝试了一些不同的方法,现在速度快了很多。我可以在大约 5 秒内读取一个 200kb 的文件,所以这是一个改进,但是我需要打开大约 5 个这些文件,每个 5 秒仍然很长,所以我将使用 SQL lite 并查询数据反而。我已经编程了很长时间,但是我是android和Java的新手,所以这更像是一个学习练习。非常感谢所有的建议!

标签: android sd-card fileinputstream


【解决方案1】:

在字符串上使用+=非常效率低下 - 它会不断分配和释放内存,这是您需要避免的!

如果您需要不断添加字符,请使用 StringBuilder 并预先为其提供足够大的缓冲区。

但是,最好将整个文件作为字节数组读取,然后从该字节数组创建一个字符串。使用String(byte[]) 构造函数。

【讨论】:

  • 我知道。在否决任何事情时应该有一个强制性的评论。否则对任何人都没有帮助。
  • 我同意,这绝对是应该实施的。会避开很多因为意见不同意而只是投反对票的人。
  • 似乎高层不同意:meta.stackexchange.com/questions/135/…。他们的解决方案是添加“您可能想要添加评论并解释您的反对票”提示。
  • 嗯,是的,我明白了。 :/ 不过,我可以承认,他们确实有一些充分的理由。
  • 我现在正在使用 StringBuilder,但找不到 String(byte[]) 的工作示例。非常感谢您的回答!
【解决方案2】:

内容 += (char)c;

嗯,这是你的问题。如果您必须重复进行字符串连接,则 slow。而且您一次读取一个字符,这也很慢。

您希望使用read(byte[] buffer) 方法有效地将文件读入缓冲区。然后你可以根据需要对缓冲区进行字符串化。

【讨论】:

    【解决方案3】:

    您应该使用read(byte[]) 读取多个字节,而不是一次读取一个字节。

    此外,字符串是不可变的,因此每次执行 String s = s + "a";您可能正在创建一个新的 String 对象。您可以改用StringBuilder 来构建更大的字符串。

    【讨论】:

      【解决方案4】:

      Schlemiel the painter又来了!

      【讨论】:

      • +1 链接。我没有很多底层编程经验,但我总是喜欢阅读这样的东西!
      【解决方案5】:

      尝试使用缓冲区读取read(byte[] buff)

      【讨论】:

        【解决方案6】:

        原因是:

        1. 您使用 content += (char)c; 创建了太多 String 对象 - 使用 StringBuilder 代替附加读取数据,然后在最后调用 StringBuilder 上的 toString()。
        2. 您不使用 byte[](或 char[],这取决于实现)缓冲区从文件中读取。通常 1KB 缓冲区是最佳的,而不是一个字节一个字节地读取。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-11
          • 2013-05-19
          • 2019-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多