Статьи

Java: пошаговое чтение / потоковая передача файла CSV

Я проделал некоторую работу, которая включает чтение в файлах CSV, для которых я использовал OpenCSV , и мой первоначальный подход состоял в том, чтобы построчно просматривать файл, анализировать содержимое и сохранять его в списке карт.

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

Первоначально я написал вариант строк String # для totallazy, чтобы сделать это, и, хотя я был в состоянии передать файл, я где-то допустил ошибку, которая означала, что количество карт в куче всегда увеличивалось.

Потратив несколько часов на попытки исправить это, Майкл предположил, что вместо этого будет проще использовать итератор, и я получил следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class ParseCSVFile {
    public static void main(String[] args) throws IOException
    {
        final CSVReader csvReader = new CSVReader( new BufferedReader( new FileReader( "/path/to/file.csv" ) ), '\t' );
        final String[] fields = csvReader.readNext();
 
        Iterator<Map<String, Object>>() lazilyLoadedFile = return new Iterator<Map<String, Object>>()
        {
            String[] data = csvReader.readNext();
 
            @Override
            public boolean hasNext()
            {
                return data != null;
            }
 
            @Override
            public Map<String, Object> next()
            {
                final Map<String, Object> properties = new HashMap<String, Object>();
                for ( int i = 0; i < data.length; i++ )
                {
                    properties.put(fields[i], data[i]);
                }
 
                try
                {
                    data = csvReader.readNext();
                }
                catch ( IOException e )
                {
                    data = null;
                }
 
                return properties;
            }
 
            @Override
            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }  
}

Хотя этот код работает, это не самая читаемая функция, которую я когда-либо писал, поэтому любые предложения о том, как сделать это более чистым способом, приветствуются.