简体   繁体   中英

How to convert multi-line records from text file to Stream<List<String>>?

I have a text file containing records such as:

--------------------
Field1=Value1
Field2=Value2
Field3=Value3
EOR
---------------------
Field1=Value1
Field2=Value2
Field3=Value3
Field4=Value4
Field5=Value5
EOR

Each record can have multiple lines. The end of each record is marked by the word "EOR".

I would like to process these lines from a text file into a stream of records eg, Stream<List<Record>> . So far, I am only able to get a Stream<String> form the file with Files.lines(pathToFile)), where each element is a line.

I am looking for a way to convert this stream of Strings into a stream of List<String> .

With StreamEx library

StreamEx.of(Files.lines(pathToFile))
    .groupRuns((s, s2) -> !"EOR".equals(s))
    .collect(Collectors.toList()));

Assuming you don't want to bring in any dependencies, it is pretty simple to write an Iterator and then stream it.

public class SampleJava {
public static void main(String args[]) throws IOException {
    try(Stream<String> lines = Files.lines(Paths.get("records.txt"))) {
        new RecordIterator(lines).stream().forEach(System.out::println);
    }
}
static class RecordIterator implements Iterator<List<String>>
{
    private final static String SEP = "---";
    private final static String EOR = "EOR";
    private final Iterator<String> lines;
    public RecordIterator(Stream<String> lines) {
        this.lines = lines.iterator();
    }
    @Override
    public boolean hasNext() {
        return lines.hasNext();
    }
    @Override
    public List<String> next() {
        if(!hasNext()) throw new NoSuchElementException();
        List<String> record = new ArrayList<>();
        do {
            String next = lines.next();
            if(next.startsWith(SEP)) continue;
            if(next.equals(EOR)) break;
            record.add(next);
        } while(hasNext());
        return record;
    }
    public Stream<List<String>> stream() {
        Iterable<List<String>> itor = ()-> this;
        return StreamSupport.stream(itor.spliterator(), false);
    }
}
}

Output:

[Field1=Value1, Field2=Value2, Field3=Value3]

[Field1=Value1, Field2=Value2, Field3=Value3, Field4=Value4, Field5=Value5]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM