Потоки повсюду в Java 8. Просто посмотрите вокруг, и вы наверняка найдете их. Это также относится к java.io.BufferedReader . Парсинг файла в Java 8 с Stream API чрезвычайно прост.
У меня есть файл CSV, который я хочу прочитать. Пример ниже:
|
1
2
3
|
username;visitedjdoe;10kolorobot;4 |
Контракт для моего читателя заключается в предоставлении заголовка в виде списка строк и всех записей в виде списка строк. Мой читатель принимает java.io.Reader в качестве источника для чтения.
Начну с чтения шапки. Алгоритм чтения заголовка выглядит следующим образом:
- Откройте источник для чтения,
- Получить первую строку и разобрать ее,
- Разделить линию разделителем,
- Получить первую строку и разобрать ее,
- Преобразовать строку в список строк и вернуть.
И реализация:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
class CsvReader { private static final String SEPARATOR = ";"; private final Reader source; CsvReader(Reader source) { this(source); } List<String> readHeader() { try (BufferedReader reader = new BufferedReader(source)) { return reader.lines() .findFirst() .map(line -> Arrays.asList(line.split(SEPARATOR))) .get(); } catch (IOException e) { throw new UncheckedIOException(e); } } } |
Довольно просто. Интуитивно понятный. Точно так же я создал метод для чтения всех записей. Алгоритм чтения записей выглядит следующим образом:
- Откройте источник для чтения,
- Пропустить первую строку,
- Разделить линию разделителем,
- Примените маппер к каждой строке, которая отображает строку в список строк.
И реализация:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
class CsvReader { List<List<String>> readRecords() { try (BufferedReader reader = new BufferedReader(source)) { return reader.lines() .substream(1) .map(line -> Arrays.asList(line.split(separator))) .collect(Collectors.toList()); } catch (IOException e) { throw new UncheckedIOException(e); } } } |
Ничего особенного здесь. Что вы могли заметить, так это то, что картограф в обоих методах абсолютно одинаков. Фактически, это может быть легко извлечено в переменную:
|
1
2
|
Function<String, List<String>> mapper = line -> Arrays.asList(line.split(separator)); |
Чтобы закончить, я создал простой тест.
|
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
|
public class CsvReaderTest { @Test public void readsHeader() { CsvReader csvReader = createCsvReader(); List<String> header = csvReader.readHeader(); assertThat(header) .contains("username") .contains("visited") .hasSize(2); } @Test public void readsRecords() { CsvReader csvReader = createCsvReader(); List<List<String>> records = csvReader.readRecords(); assertThat(records) .contains(Arrays.asList("jdoe", "10")) .contains(Arrays.asList("kolorobot", "4")) .hasSize(2); } private CsvReader createCsvReader() { try { Path path = Paths.get("src/test/resources", "sample.csv"); Reader reader = Files.newBufferedReader( path, Charset.forName("UTF-8")); return new CsvReader(reader); } catch (IOException e) { throw new UncheckedIOException(e); } }} |
| Ссылка: | Анализ файла с Stream API в Java 8 от нашего партнера по JCG Рафаля Боровца в блоге Codeleak.pl . |