Открытие 12 КБ текстового файла занимает слишком много времени ....? - PullRequest
3 голосов
/ 02 декабря 2010

Следующий код работает, но занимает слишком много времени (более минуты), чтобы открыть маленький файл. LogCat показывает много экземпляров "GC_FOR_MALLOC освобожденных #### объектов / ###### байтов за ## мс". Есть предложения?

 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;
}

Спасибо всем !!

Ответы [ 6 ]

6 голосов
/ 02 декабря 2010

Использование += в строке крайне неэффективно - оно будет постоянно выделять и освобождать память, чего вам следует избегать!

Если вам нужно постоянно добавлять символы, используйтеStringBuilder и заранее выделите ему достаточно большой буфер.

Однако даже лучше просто прочитать весь файл в виде байтового массива, а затем создать строку из этого байтового массива.Используйте конструктор String(byte[]).

2 голосов
/ 02 декабря 2010

Шлемель, художник снова наносит удар!

2 голосов
/ 02 декабря 2010

Вместо чтения одного байта за раз, вы должны прочитать несколько, используя read (byte []) .

Кроме того, строки являются неизменяемыми, поэтому каждый раз, когда вы делаете String s = s + "a"; есть вероятность, что вы создаете новый объект String. Вместо этого вы можете использовать StringBuilder , чтобы создать большую строку.

2 голосов
/ 02 декабря 2010

content + = (char) c;

Ну, вот твоя проблема. Конкатенация строк медленная , если вам придется делать это повторно. И вы читаете файл по одному символу за раз, что тоже очень медленно.

Вы хотите использовать метод read(byte[] buffer) для эффективного чтения файла в буфер. И тогда вы можете при необходимости зашифровать буфер.

0 голосов
/ 02 декабря 2010

Причины:

  1. Вы создаете слишком много объектов String с помощью content += (char)c; - вместо этого используйте StringBuilder для добавления с прочитанными данными, затем в конце вызывайте toString () для StringBuilder.
  2. Вы не используете буфер байтов [] (или char [], это зависит от реализации) для чтения из файла. Обычно оптимальным является буфер размером 1 КБ вместо чтения по одному байту.
0 голосов
/ 02 декабря 2010

попытка чтения из буфера чтение (байт [] бафф)

...