NIO extensions for Apache Groovy providing enhanced file system operations and path handling
—
Process files line-by-line with closures, including splitting, filtering, and transformation operations with comprehensive charset support.
Iterate through file lines with closures, supporting line numbers and charset options.
/**
* Iterates through this path line by line. Each line is passed to the given 1 or 2 arg closure
* @param self a Path
* @param closure a closure (arg 1 is line, optional arg 2 is line number starting at line 1)
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T eachLine(Path self, Closure<T> closure);
/**
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
* @param self a Path
* @param charset opens the file with a specified charset
* @param closure a closure (arg 1 is line, optional arg 2 is line number starting at line 1)
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T eachLine(Path self, String charset, Closure<T> closure);
/**
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
* @param self a Path
* @param firstLine the line number value used for the first line (default is 1, set to 0 to start counting from 0)
* @param closure a closure (arg 1 is line, optional arg 2 is line number)
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T eachLine(Path self, int firstLine, Closure<T> closure);
/**
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
* @param self a Path
* @param charset opens the file with a specified charset
* @param firstLine the line number value used for the first line (default is 1, set to 0 to start counting from 0)
* @param closure a closure (arg 1 is line, optional arg 2 is line number)
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T eachLine(Path self, String charset, int firstLine, Closure<T> closure);Usage Examples:
import java.nio.file.Path
import java.nio.file.Paths
Path file = Paths.get("data.txt")
// Simple line iteration
file.eachLine { line ->
println line
}
// With line numbers (starting from 1)
file.eachLine { line, lineNumber ->
println "${lineNumber}: ${line}"
}
// With charset
file.eachLine("UTF-8") { line ->
println line
}
// With custom starting line number (0-based)
file.eachLine(0) { line, lineNumber ->
println "Line ${lineNumber}: ${line}"
}
// With charset and custom starting line number
file.eachLine("UTF-8", 0) { line, lineNumber ->
println "[${lineNumber}] ${line}"
}
// Collect lines (return value from closure)
List<String> upperCaseLines = file.eachLine { line ->
line.toUpperCase()
}Split each line using regular expressions or patterns, with closure processing of the split results.
/**
* Iterates through this file line by line, splitting each line using the given regex separator.
* For each line, the given closure is called with a single parameter being the list of strings
* computed by splitting the line around matches of the given regular expression
* @param self a Path
* @param regex the delimiting regular expression
* @param closure a closure
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
* @throws PatternSyntaxException if the regular expression's syntax is invalid
*/
<T> T splitEachLine(Path self, String regex, Closure<T> closure);
/**
* Iterates through this file line by line, splitting each line using the given separator Pattern.
* For each line, the given closure is called with a single parameter being the list of strings
* computed by splitting the line around matches of the given regular expression Pattern
* @param self a Path
* @param pattern the regular expression Pattern for the delimiter
* @param closure a closure
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T splitEachLine(Path self, Pattern pattern, Closure<T> closure);
/**
* Iterates through this file line by line, splitting each line using the given regex separator.
* For each line, the given closure is called with a single parameter being the list of strings
* computed by splitting the line around matches of the given regular expression
* @param self a Path
* @param regex the delimiting regular expression
* @param charset opens the file with a specified charset
* @param closure a closure
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
* @throws PatternSyntaxException if the regular expression's syntax is invalid
*/
<T> T splitEachLine(Path self, String regex, String charset, Closure<T> closure);
/**
* Iterates through this file line by line, splitting each line using the given regex separator Pattern.
* For each line, the given closure is called with a single parameter being the list of strings
* computed by splitting the line around matches of the given regular expression
* @param self a Path
* @param pattern the regular expression Pattern for the delimiter
* @param charset opens the file with a specified charset
* @param closure a closure
* @return the last value returned by the closure
* @throws IOException if an IOException occurs
*/
<T> T splitEachLine(Path self, Pattern pattern, String charset, Closure<T> closure);Usage Examples:
import java.nio.file.Path
import java.nio.file.Paths
import java.util.regex.Pattern
Path csvFile = Paths.get("data.csv")
// Split CSV lines by comma
csvFile.splitEachLine(",") { fields ->
println "Name: ${fields[0]}, Age: ${fields[1]}, City: ${fields[2]}"
}
// Split with regex pattern
csvFile.splitEachLine(/\s*,\s*/) { fields ->
// Handle CSV with spaces around commas
println fields.join(" | ")
}
// Using Pattern object
Pattern tabPattern = Pattern.compile("\t")
Path tsvFile = Paths.get("data.tsv")
tsvFile.splitEachLine(tabPattern) { fields ->
println "Tab-separated: ${fields}"
}
// With charset
csvFile.splitEachLine(",", "UTF-8") { fields ->
println "Unicode data: ${fields}"
}
// Process log file with pipe separator
Path logFile = Paths.get("server.log")
logFile.splitEachLine("\\|") { parts ->
def timestamp = parts[0]
def level = parts[1]
def message = parts[2]
if (level == "ERROR") {
println "Error at ${timestamp}: ${message}"
}
}Filter file lines based on closure predicates, returning Writable objects or writing to output streams.
/**
* Filters the lines of a Path and creates a Writable in return to stream the filtered lines
* @param self a Path
* @param closure a closure which returns a boolean indicating to filter the line or not
* @return a Writable closure
* @throws IOException if self is not readable
*/
Writable filterLine(Path self, Closure closure);
/**
* Filters the lines of a Path and creates a Writable in return to stream the filtered lines
* @param self a Path
* @param charset opens the file with a specified charset
* @param closure a closure which returns a boolean indicating to filter the line or not
* @return a Writable closure
* @throws IOException if an IOException occurs
*/
Writable filterLine(Path self, String charset, Closure closure);
/**
* Filter the lines from this Path, and write them to the given writer based on the given closure predicate
* @param self a Path
* @param writer a writer destination to write filtered lines to
* @param closure a closure which takes each line as a parameter and returns true if the line should be written to this writer
* @throws IOException if self is not readable
*/
void filterLine(Path self, Writer writer, Closure closure);
/**
* Filter the lines from this Path, and write them to the given writer based on the given closure predicate
* @param self a Path
* @param writer a writer destination to write filtered lines to
* @param charset opens the file with a specified charset
* @param closure a closure which takes each line as a parameter and returns true if the line should be written to this writer
* @throws IOException if an IO error occurs
*/
void filterLine(Path self, Writer writer, String charset, Closure closure);Usage Examples:
import java.nio.file.Path
import java.nio.file.Paths
Path logFile = Paths.get("application.log")
Path errorLog = Paths.get("errors.log")
// Filter lines and get Writable
Writable errorLines = logFile.filterLine { line ->
line.contains("ERROR")
}
// Write filtered lines to another file
errorLog.withWriter { writer ->
errorLines.writeTo(writer)
}
// Filter directly to writer
errorLog.withWriter { writer ->
logFile.filterLine(writer) { line ->
line.contains("ERROR") || line.contains("FATAL")
}
}
// Filter with charset
logFile.filterLine("UTF-8") { line ->
line.startsWith("[WARN]")
}.writeTo(System.out)
// Complex filtering example
Path accessLog = Paths.get("access.log")
Path suspiciousLog = Paths.get("suspicious.log")
suspiciousLog.withWriter { writer ->
accessLog.filterLine(writer, "UTF-8") { line ->
// Filter for potential security issues
line.contains("404") ||
line.contains("sql") ||
line.contains("script") ||
line.contains("admin")
}
}Process files byte-by-byte or in buffered chunks with closures.
/**
* Traverse through each byte of this Path
* @param self a Path
* @param closure a closure
* @throws IOException if an IOException occurs
*/
void eachByte(Path self, Closure closure);
/**
* Traverse through the bytes of this Path, bufferLen bytes at a time
* @param self a Path
* @param bufferLen the length of the buffer to use
* @param closure a 2 parameter closure which is passed the byte[] and a number of bytes successfully read
* @throws IOException if an IOException occurs
*/
void eachByte(Path self, int bufferLen, Closure closure);Usage Examples:
import java.nio.file.Path
import java.nio.file.Paths
Path binaryFile = Paths.get("data.bin")
// Process each byte individually
binaryFile.eachByte { byte b ->
printf("%02X ", b)
}
// Process bytes in 1KB chunks
binaryFile.eachByte(1024) { byte[] buffer, int bytesRead ->
println "Read ${bytesRead} bytes"
// Process buffer[0] to buffer[bytesRead-1]
for (int i = 0; i < bytesRead; i++) {
// Process buffer[i]
}
}
// Calculate file checksum
def checksum = 0
binaryFile.eachByte { byte b ->
checksum += (b & 0xFF)
}
println "Simple checksum: ${checksum}"Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy-nio