Записать ArrayList<String[]> в txt файл

170
03 ноября 2018, 10:20

Подскажите пожалуйста, как записать большой (5000 строк) ArrayList<String[]> в файл через разделитель. String[] состоит из 13 элементов.

Сейчас делаю так, перебираю все строки и добавляю между ними разделители, потом записываю в файл.. Но на 5000 строк уходит до 20 секунд, это очень долго..
"﹀" - это у меня разделители в текстовом файле..

ArrayList<String[]> myPoints;
...
public void mySavePoints(final String file_name) {
    String txt = "";  //составляем текст в файле
    if (myPoints.size() > 0) {
        for (int i = 0; i < myPoints.size(); i++) {
            txt =  txt + myPoints.get(i)[0]                 + "﹀" +
                    myPoints.get(i)[1].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[2]                      + "﹀" +
                    myPoints.get(i)[3]                      + "﹀" +
                    myPoints.get(i)[4]                      + "﹀" +
                    myPoints.get(i)[5].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[6].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[7].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[8].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[9].replaceAll("﹀", "^")   + "﹀" +
                    myPoints.get(i)[10].replaceAll("﹀", "^")  + "﹀" +
                    myPoints.get(i)[11].replaceAll("﹀", "^")  + "﹀" +
                    myPoints.get(i)[12].replaceAll("﹀", "^")  + "\n";
        }
    }

    // поток
    final String finalTxt = txt;
    Thread thread = new Thread() {
        @Override
        public void run() {
            //Сохраняем переменную в файл
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file_name);
                byte[] buffer = finalTxt.getBytes();
                fos.write(buffer, 0, buffer.length);
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if(fos != null)
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
            //конец потока
        }
    };
    thread.start();
}
Answer 1

Время у вас уходит на создание огромного количества строк в цикле, это классическая ошибка, о которой много где написано.

Плюс к этому непонятно, зачем сперва делать делать строку, а потом писать её, если можно сразу писать в файл? Таким образом вам не нужно держать эту большую строку в памяти:

private static final Set<Integer> REPLACE_INDEXES = new HashSet<>(Arrays.asList(1,5,6,7,8,9,10,11,12));
private final int STRING_ARRAY_SIZE = 13;
public void mySavePoints(final String fileName) throws IOException {
    FileWriter fw = new FileWriter(fileName);
    for (int i = 0; i < myPoints.size(); i++) {
        for(int j = 0; j < STRING_ARRAY_SIZE; j++){
            if(REPLACE_INDEXES.contains(j)){
                fw.write(myPoints.get(i)[j].replaceAll("﹀", "^"));
            } else {
                fw.write(myPoints.get(i)[j]);
            }
            fw.write('﹀');
        }
        fw.write("\n");
    }
    fw.close();
}
Answer 2

Дело в том, что объекты класса String - неизменяемы, то есть вы добавляя что-то к стринге, вы создаёте новый объект, сохранив старый. У вас - чистая утечка памяти. Используйте класс StringBuilder - это аналог String, только изменяемый. Итак:

Создайте объект класса StringBuilder:

StringBuilder out = new StringBuilder(""); //Строка для записи массива строк

В эту строку запишите весь массив строк.

for(int i = 0; i<myPoints.size(); i++){
    out.append(myPoints.get(i));
    }

Полученную строку запишите в txt.

По моему авторитетному мнению, должно получаться 0.5-5 секунд на всё.

READ ALSO
Ошибка 500 The server encountered an unexpected condition that prevented it from fulfilling the request. (tiles, JSP, Java)

Ошибка 500 The server encountered an unexpected condition that prevented it from fulfilling the request. (tiles, JSP, Java)

Пытался прикрутить к простейшему проекту tiles из примера https://o7planningorg/ru/11683/spring-boot-apache-tiles-jsp-tutorial все вроде делал по писанному, за исключением...

179
Android Studio, не работает get запрос

Android Studio, не работает get запрос

Делаю практическое задание для универа на Android Studio, мне нужно делать get запросы к странице, чтобы получать данные с БД, но ни один из найденных...

181
Не могу найти правильный подход к изучению Java и разработки под Android

Не могу найти правильный подход к изучению Java и разработки под Android

я начинающий программист, изучаю Java и хочу изучать разработку под AndroidПроблема в том, что я не могу найти правильный подход к изучению, и меня...

169