Skip to content

ajlane/iostreams

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IOStreams

javadoc build-status codecov

Composable heavy-weight iterators for Java.

An IOStream provides hasNext and next methods, just like an Iterator, but is also Closeable and throws predictable checked exceptions.

Like Iterable, IOStreamable types can provide fresh instances of IOStream to provide sequential access to a resource.

Utility methods on IOStreams and IOStreamables allow streams to be transformed and composed.

IOStreams is provided under the Apache License Version 2.0.

Example

This example uses IOStreams to lazily read the given text files and output their contents line-by-line.

public static void main(final String... args) throws IOStreamException, InterruptedException
{
    // Start with a list of file names
    IOStreams.fromArray(args)
        // Read each line from each file
        .flatMap(file -> FileLineIOStream.fromFile(Paths.get(file), StandardCharsets.UTF_8))
        // Filter out empty lines or lines that start with a comment
        .skip(line -> line.text.matches("\\s*(#.*)?"))
        // Prefix with the path and line number, and trim whitespace and comments from the lines that are left
        .map(line -> line.path + "\t" + line.number + "\t" + line.text.replaceAll("^\\s+|\\s*#.*$", ""))
        // Consume each file by printing uncommented lines to standard out.
        .consume(System.out::println);
}

Why not just write a couple of loops?

Sure, let's have a look at that version.

public static void main(final String... args) throws IOException, InterruptedException{
    // Start with a list of file names
    for(String file : args){
        // Read each line from each file
        try(final BufferedReader reader = Files.newBufferedReader(Paths.get(file), StandardCharsets.UTF_8)){
            int lineNumber = 0;
            for(String lineText = reader.readLine(); lineText != null; lineText = reader.readLine(), lineNumber++){
                if(Thread.interrupted()) throw new InterruptedException();
                // Filter out empty lines or lines that start with a comment
                if(lineText.matches("\\s*(#.*)?")) {
                    // Prefix with the path and line number, and trim whitespace and comments from the lines that are left
                    String result = file + "\t" + lineNumber + "\t" + lineText.replaceAll("^\\s+|\\s*#.*$", "");
                    // Consume each file by printing uncommented lines to standard out
                    System.out.println(result)
                }
            }
        }
    }
}

It's just as concise, and doesn't use any libraries. If this is all you need, use this instead. But! Notice that there are three nested bits of logic here:

  • Opening and closing files
  • Filtering and transforming lines of text
  • Displaying results

In the IOStreams example, these are all independent - you could swap out the call to System.out.println with something that writes results to another file, without changing the reading or filtering code at all. IOStreams allows you to better encapsulate and modularise your data processing code.

Maven

IOStreams is available in Maven Central.

<dependency>
  <groupId>au.id.ajlane.iostreams</groupId>
  <artifactId>iostreams</artifactId>
  <version>0.0.9</version>
</dependency>

About

Composable heavy-weight iterators for Java

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages