2015-07-21 5 views
2

У меня очень большие файлы csv, которые я пытаюсь выполнить итерацией. Я использую opencsv, и я бы хотел использовать CsvToBean, чтобы я мог динамически устанавливать сопоставления столбцов из базы данных. У меня есть вопрос, как это сделать, не захватывая весь файл и не бросая его в список. Я пытаюсь предотвратить ошибки памяти.Как обрабатывать большой файл csv или читать большой CSV-файл в кусках

В настоящее время я передаю весь набор результатов в список.

List<MyOption> myObjects = csv.parse(strat, getReader("file.txt")); 

for (MyObject myObject : myObjects) { 
    System.out.println(myObject); 
} 

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

Iterator myObjects = csv.parse(strat, getReader("file.txt")).iterator(); 

while (myObjects.hasNext()) { 
    MyObject myObject = (MyObject) myObjects.next(); 
    System.out.println(myObject); 
} 

Так что мой вопрос в чем разница между Итератором и списком?

+0

возможной Dupli cate из [List vs List iterator] (http://stackoverflow.com/questions/8411302/list-vs-list-iterator) –

+0

http://stackoverflow.com/questions/2113216/which-is-more-efficient- a-for-each-loop-or-iterator –

+1

в любом случае, CsvToBean всегда будет анализировать весь файл в списке и возвращать его (согласно источнику, который я нашел в google). Если вы хотите обработать произвольно большой файл, вам понадобится синтаксический анализатор, который читает одну строку во времени, возвращая один компонент во времени. – slipperyseal

ответ

1

Усовершенствованный цикл (for (MyObject myObject : myObjects)) осуществляется с помощью Iterator (это требует, чтобы экземпляр, возвращаемый csv.parse(strat, getReader("file.txt")) реализует интерфейс Iterable, который содержит iterator() метод, который возвращает Iterator), так что нет никакой разницы в производительности между двумя кодом сниппеты.

P.S

Во втором фрагменте, не используйте сырые Iterator типа, используйте Iterator<MyObject>:

Iterator<MyObject> myObjects = csv.parse(strat, getReader("file.txt")).iterator(); 

while (myObjects.hasNext()) { 
    MyObject myObject = myObjects.next(); 
    System.out.println(myObject); 
} 
+0

Итак, по звукам этого мне нужно будет использовать метод итератора и реализовать собственный CSVToBean. –

+0

Спасибо за подсказку, но это не похоже на использование итератора для решения моих проблем с памятью:/ –

+0

@CodeJunkie Вопрос в том, может ли используемый вами экземпляр 'csv' предоставить« Итератор », который не требует сначала создание списка (поскольку создание списка требует предварительного считывания всех данных). Такой Итератор (если существует) может считывать данные из файла по требованию (когда вы вызываете метод 'hasNext()' или 'next()'). – Eran

1

Чтение большого файла CSV сразу не является хорошим решением. Лучший способ прочитать файл csv в кусках. Вы можете иметь несколько потоков для чтения данных из файла и нескольких других потоков для выполнения бизнес-логики. Более подробная информация для чтения CSV-данных в кусках приведена здесь How to parse chunk by chunk a large CSV file and bulk insert to a database и имеет несколько решений threds here

1

«В чем разница между Итератором и списком?»

Перечень представляет собой структуру данных, которая дает функциональные возможности пользователя, как получить(), ToArray() и т.д.

Итератор только может позволить пользователю перемещаться через структуру данных, при условии, что структура данных реализует интерфейс итератора (что делают все структуры данных)

так List<MyOption> myObjects = csv.parse(strat, getReader("file.txt")); физически хранит данные в myObjects

и Iterator myObjects = csv.parse(strat, getReader("file.txt")).iterator(); просто использует функциональные возможности итератора из csv.parse