Недавно я хотел извлечь определенные данные из выходного журнала. Вот часть файла журнала:
1
2
3
4
5
|
2015-01-06 11:33:03 b.s.d.task [INFO] Emitting: eVentToRequestsBolt __ack_ack [-6722594615019711369 -1335723027906100557] 2015-01-06 11:33:03 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package com.foo.bar 2015-01-06 11:33:04 b.s.d.executor [INFO] Processing received message source : eventToManageBolt:2, stream: __ack_ack, id : {}, [-6722594615019711369 -1335723027906100557] 2015-01-06 11:33:04 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package co.il.boo 2015-01-06 11:33:04 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package dot.org.biz |
Я решил сделать это, используя функции Java8 Stream и Lambda Expression.
Читать файл
Во-первых, мне нужно было прочитать файл журнала и поместить строки в поток:
1
|
Stream<String> lines = Files.lines(Paths.get(args[ 1 ])); |
Фильтровать соответствующие строки
Мне нужно было получить имена пакетов и записать их в другой файл. Не все строки содержат данные, которые мне нужны, поэтому отфильтруйте только релевантные
1
|
lines.filter(line -> line.contains( "===---> Loaded package" )) |
Разбор соответствующих строк
Затем мне нужно было разобрать соответствующие строки. Я сделал это, сначала разбив каждую строку на массив строк, а затем взяв последний элемент в этом массиве. Другими словами, я сделал двойное отображение . Сначала строка в массив, а затем массив в строку.
1
2
|
.map(line -> line.split( " " )) .map(arr -> arr[arr.length - 1 ]) |
Запись в выходной файл
Последняя часть брала каждую строку и записывала ее в файл. Это была терминальная операция.
1
|
.forEach( package -> writeToFile(fw, package )); |
writeToFile — метод, который я создал. Причина в том, что файловая система Java выдает IOException. Вы не можете использовать проверенные исключения в лямбда-выражениях.
Вот полный пример (обратите внимание, я не проверяю ввод)
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
46
47
48
49
|
import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class App { public static void main(String[] args) throws IOException { Stream<String> lines = null ; if (args.length == 2 ) { lines = Files.lines(Paths.get(args[ 1 ])); } else { String s1 = "2015-01-06 11:33:03 b.s.d.task [INFO] Emitting: adEventToRequestsBolt __ack_ack [-6722594615019711369 -1335723027906100557]" ; String s2 = "2015-01-06 11:33:03 b.s.d.executor [INFO] Processing received message source: eventToManageBolt:2, stream: __ack_ack, id: {}, [-6722594615019711369 -1335723027906100557]" ; String s3 = "2015-01-06 11:33:04 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package com.foo.bar" ; String s4 = "2015-01-06 11:33:04 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package co.il.boo" ; String s5 = "2015-01-06 11:33:04 c.s.p.d.PackagesProvider [INFO] ===---> Loaded package dot.org.biz" ; List<String> rows = Arrays.asList(s1, s2, s3, s4, s5); lines = rows.stream(); } new App().parse(lines, args[ 0 ]); } private void parse(Stream<String> lines, String output) throws IOException { final FileWriter fw = new FileWriter(output); //@formatter:off lines.filter(line -> line.contains( "===---> Loaded package" )) .map(line -> line.split( " " )) .map(arr -> arr[arr.length - 1 ]) .forEach( package -> writeToFile(fw, package )); //@formatter:on fw.close(); lines.close(); } private void writeToFile(FileWriter fw, String package ) { try { fw.write(String.format( "%s%n" , package )); } catch (IOException e) { throw new RuntimeException(e); } } } |
Ссылка: | Java 8 Stream и Lambda Expressions — пример анализа файла от нашего партнера по JCG Эяля Голана в блоге « Обучение и совершенствование в качестве мастера» . |