#java #android #performance #csvreader
Вопрос:
Мне нужно открыть csv-файл в большем количестве частей, каждая по 5000 образцов, а затем построить их. Чтобы переходить назад и вперед по сигналу каждый раз, когда я нажимаю кнопку, мне нужно создать экземпляр нового считывателя, а затем я перехожу к нужной мне точке. Мой сигнал большой, составляет около 135 000 выборок, поэтому метод CSVReader.skip() очень медленный, когда я работаю с последними выборками. Но чтобы вернуться назад, я не могу удалять строки, поэтому каждый раз мой итератор нужно создавать заново. Я заметил, что скип использует цикл for? Есть ли лучший способ решить эту проблему? Вот мой код:
public void updateSign(int segmento) {
Log.d("segmento", Integer.toString(segmento));
//check if I am in the signal length
if (segmento>0 amp;amp; (float)(segmento-1)<=(float)TOTAL/normaLen)
{
try {
reader = new CSVReader(new FileReader(new File(patty)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<Integer> sign = new ArrayList<>();
//this is the point of the signal where i finish
int len = segmento * normaLen;
//check if i am at the end of the signal
if (len >= TOTAL) {
len = TOTAL;
segmento=0;
avanti.setValue(false);
System.out.println(avanti.getValue());
} else {
lines = TOTAL - len;
avanti.setValue(true);
System.out.println(avanti.getValue());
}
//the int to i need to skip
int skipper = (segmento-1)*normaLen;
try {
System.out.println("pre skip");
reader.skip(skipper);
System.out.println("post skip");
} catch (IOException e) {
e.printStackTrace();
}
//my iterator
it = reader.iterator();
System.out.println("iteratore fatto");
//loop to build my mini-signal to plot
//having only 5,000 sample it is fast enaugh
for (int i = skipper; i < len-1; i ) {
if (i>=(segmento-1)*normaLen) {
sign.add(Integer.parseInt(it.next()[0]));
}
else
{
it.next();
System.out.println("non ha funzionato lo skip");
}
}
System.out.println("ciclo for: too much fatica?");
//set sign to be plotted by my fragment
liveSign.setValue(sign);
}
}
Заранее спасибо!
Комментарии:
1. Я вижу два варианта: преобразовать ваш CSV в структуру данных, поддерживающую произвольный доступ (например, ArrayList), или вы помните, где начинается каждая строка файла, и используете RandomAccessFile, хотя это довольно трудоемко. Программа CSVReader не может перейти к строке, потому что строки имеют разную длину, и хранение информации будет стоить памяти однократное прохождение всего файла.
2. Я думал открыть весь свой файл в arraylist/массив, но он слишком большой, поэтому замедляет работу моего приложения. Есть ли способ, как я могу сделать это быстрее?
3. Сколько у вас записей? Из кода вы считываете только одно целое число из позиции 0. Хранение 135 000 целых чисел не занимает много памяти. Вы сохранили целые числа или весь файл целиком?
4. Я открываю его и сохраняю в ArrayList<Целое число>. Чтобы открыть файл, требуется некоторое время. Кстати, это простой случай, потому что у меня также может быть что-то около 5 миллионов записей (сигналы поступают с экг при полисомнографии, поэтому выборка при 125 Гц за ночь дает много выборок).
5. У вас есть несколько вариантов. Например: 1. если вы не придерживаетесь формата csv, я бы предложил использовать некоторую двоичную кодировку для создания строки фиксированной длины (8 байт на длинную/двойную, некоторое фиксированное количество байтов для строкового значения и т. Д. и т. Д.) И использовать RandomAccessFile. Пример такой кодировки bin можно найти в jvm hg.openjdk.java.net/jdk8/jdk8/jdk/file/00cd9dc3c2b5/src/share/… , КСТАТИ. Поскольку размер каждой строки фиксирован (и одинаков), легко рассчитать смещение для чтения строки с любым индексом 2. Используйте встроенное хранилище, такое как MapDB, H2 и т. Д.