Apache Groovy is a powerful multi-faceted programming language for the JVM platform
—
Enhanced file system operations, stream processing, and I/O utilities through Groovy extensions to Java's I/O classes. Provides simplified file manipulation, automatic resource management, and powerful text processing capabilities.
Enhanced file operations with automatic resource management and Groovy-specific convenience methods.
/**
* Extension methods added to java.io.File class
*/
class File {
/**
* Read entire file content as String with default encoding
*/
String getText();
String getText(String charset);
/**
* Write text content to file, creating parent directories if needed
*/
void setText(String text);
void setText(String text, String charset);
/**
* Append text to file
*/
void append(String text);
void append(String text, String charset);
/**
* Read file as byte array
*/
byte[] getBytes();
/**
* Write byte array to file
*/
void setBytes(byte[] bytes);
/**
* Iterate over each line in file
*/
File eachLine(Closure closure);
File eachLine(String charset, Closure closure);
File eachLine(int firstLine, Closure closure);
/**
* Process file with Reader/Writer
*/
Object withReader(Closure closure);
Object withReader(String charset, Closure closure);
Object withWriter(Closure closure);
Object withWriter(String charset, Closure closure);
/**
* Process file with streams
*/
Object withInputStream(Closure closure);
Object withOutputStream(Closure closure);
/**
* Copy file operations
*/
void copyTo(File target);
void copyTo(OutputStream target);
/**
* File filtering and traversal
*/
void eachFile(Closure closure);
void eachFileRecurse(Closure closure);
void eachDir(Closure closure);
void eachDirRecurse(Closure closure);
/**
* File filtering with patterns
*/
void eachFileMatch(Object nameFilter, Closure closure);
void eachDirMatch(Object nameFilter, Closure closure);
/**
* Directory operations
*/
boolean deleteDir();
File[] listFiles(Closure filter);
/**
* Create directory structure
*/
boolean mkdirs();
/**
* File size in human readable format
*/
String size();
}Usage Examples:
import java.io.File
// Reading files
def configFile = new File('config.properties')
def configText = configFile.getText()
println "Config content: $configText"
// Reading with specific encoding
def utf8Content = new File('data.txt').getText('UTF-8')
// Writing files
def outputFile = new File('output.txt')
outputFile.setText("Hello World\nFrom Groovy!")
// Appending to files
outputFile.append("\nAppended line")
outputFile.append("\nAnother line", 'UTF-8')
// Processing large files line by line
def logFile = new File('application.log')
logFile.eachLine { line, lineNumber ->
if (line.contains('ERROR')) {
println "Error on line $lineNumber: $line"
}
}
// Skip first line (header)
def csvFile = new File('data.csv')
csvFile.eachLine(2) { line ->
def columns = line.split(',')
println "Processing: ${columns[0]}"
}
// Safe file processing with automatic resource cleanup
def dataFile = new File('large-data.txt')
def wordCount = dataFile.withReader { reader ->
def count = 0
reader.eachLine { line ->
count += line.split(/\s+/).size()
}
return count
}
println "Total words: $wordCount"
// Binary file operations
def imageFile = new File('photo.jpg')
def imageBytes = imageFile.getBytes()
def backupFile = new File('photo-backup.jpg')
backupFile.setBytes(imageBytes)
// File copying
def sourceFile = new File('source.txt')
def targetFile = new File('target.txt')
sourceFile.copyTo(targetFile)
// Copy to stream
new FileOutputStream('output.dat').withStream { stream ->
sourceFile.copyTo(stream)
}Navigate directory structures and filter files based on various criteria.
Usage Examples:
import java.io.File
def projectDir = new File('src/main/groovy')
// Process all files in directory
projectDir.eachFile { file ->
if (file.isFile()) {
println "File: ${file.name} (${file.length()} bytes)"
} else {
println "Directory: ${file.name}"
}
}
// Recursive file processing
projectDir.eachFileRecurse { file ->
if (file.name.endsWith('.groovy')) {
println "Groovy file: ${file.relativePath}"
}
}
// Process only directories
projectDir.eachDir { dir ->
println "Package: ${dir.name}"
// Count files in each package
def fileCount = dir.listFiles({ it.isFile() } as FileFilter).length
println " Contains $fileCount files"
}
// Recursive directory processing
def rootDir = new File('.')
rootDir.eachDirRecurse { dir ->
if (dir.name == '.git') {
println "Found git repository at: ${dir.absolutePath}"
}
}
// File filtering with patterns
def sourceDir = new File('src')
sourceDir.eachFileMatch(~/.*\.java$/) { file ->
println "Java source: ${file.name}"
}
// Multiple patterns
sourceDir.eachFileMatch([~/.*\.groovy$/, ~/.*\.java$/]) { file ->
println "Source file: ${file.name}"
}
// Directory filtering
def buildDir = new File('.')
buildDir.eachDirMatch(~/test.*/) { dir ->
println "Test directory: ${dir.name}"
}
// Complex filtering with closures
projectDir.eachFileRecurse { file ->
if (file.isFile() && file.name.endsWith('.groovy')) {
def lines = file.readLines()
if (lines.any { it.contains('class ') && it.contains('Test') }) {
println "Test class: ${file.name}"
}
}
}
// Custom file filtering
def largeFiles = []
new File('.').eachFileRecurse { file ->
if (file.isFile() && file.length() > 1024 * 1024) { // > 1MB
largeFiles << file
}
}
largeFiles.sort { it.length() }.each { file ->
println "${file.name}: ${file.length()} bytes"
}Work with streams, readers, and writers using Groovy's enhanced I/O operations.
/**
* Extension methods for stream processing
*/
class InputStream {
/**
* Read entire stream as text
*/
String getText();
String getText(String charset);
/**
* Read stream as byte array
*/
byte[] getBytes();
/**
* Copy stream to OutputStream
*/
void copyTo(OutputStream target);
/**
* Process stream with closure
*/
Object withStream(Closure closure);
/**
* Iterate over lines
*/
void eachLine(Closure closure);
void eachLine(String charset, Closure closure);
}
class OutputStream {
/**
* Write text to stream
*/
void leftShift(String text);
void leftShift(byte[] bytes);
/**
* Process stream with closure
*/
Object withStream(Closure closure);
}
class Reader {
/**
* Read entire content
*/
String getText();
/**
* Iterate over lines
*/
void eachLine(Closure closure);
/**
* Copy to Writer
*/
void copyTo(Writer writer);
/**
* Filter lines
*/
void filterLines(Writer writer, Closure filter);
}
class Writer {
/**
* Write content using left shift operator
*/
Writer leftShift(String text);
Writer leftShift(Object object);
/**
* Write line
*/
void println(String text);
void println(Object object);
/**
* Write formatted text
*/
void printf(String format, Object... args);
}Usage Examples:
import java.io.*
// Reading from URLs
def url = new URL('http://example.com/data.txt')
def content = url.openStream().getText()
println content
// Stream copying
def sourceFile = new File('source.dat')
def targetFile = new File('target.dat')
sourceFile.withInputStream { input ->
targetFile.withOutputStream { output ->
input.copyTo(output)
}
}
// Processing compressed streams
def gzipFile = new File('data.gz')
gzipFile.withInputStream { fileStream ->
new GZIPInputStream(fileStream).withStream { gzipStream ->
gzipStream.eachLine { line ->
if (line.contains('ERROR')) {
println "Found error: $line"
}
}
}
}
// Writing to streams with operators
def outputFile = new File('output.txt')
outputFile.withWriter { writer ->
writer << "Header line\n"
writer << "Data: ${new Date()}\n"
writer.println("Another line")
writer.printf("Formatted: %d items processed\n", 42)
}
// Stream filtering and transformation
def logFile = new File('app.log')
def errorFile = new File('errors.log')
logFile.withReader { reader ->
errorFile.withWriter { writer ->
reader.filterLines(writer) { line ->
line.contains('ERROR') || line.contains('FATAL')
}
}
}
// Processing large files efficiently
def largeFile = new File('huge-dataset.txt')
def summary = [:]
largeFile.withReader { reader ->
reader.eachLine { line ->
def parts = line.split('\t')
if (parts.length > 2) {
def category = parts[1]
summary[category] = (summary[category] ?: 0) + 1
}
}
}
summary.each { category, count ->
println "$category: $count occurrences"
}
// Binary stream processing
def imageStream = new FileInputStream('input.jpg')
def processedStream = new FileOutputStream('processed.jpg')
imageStream.withStream { input ->
processedStream.withStream { output ->
def buffer = new byte[8192]
int bytesRead
while ((bytesRead = input.read(buffer)) != -1) {
// Process binary data
output.write(buffer, 0, bytesRead)
}
}
}Advanced text processing with encoding support and character manipulation.
/**
* Text processing utilities
*/
class StringWriter {
/**
* Get accumulated string content
*/
String toString();
/**
* Clear content
*/
void reset();
}
class CharsetToolkit {
/**
* Detect file encoding
*/
static Charset guessEncoding(File file);
static Charset guessEncoding(byte[] bytes);
/**
* Convert between encodings
*/
static String convertEncoding(String text, String fromCharset, String toCharset);
static byte[] convertEncoding(byte[] bytes, String fromCharset, String toCharset);
}Usage Examples:
import java.io.*
import java.nio.charset.Charset
// String building with StringWriter
def content = new StringWriter()
content << "Line 1\n"
content << "Line 2\n"
content.println("Line 3")
def result = content.toString()
// Processing files with different encodings
def latinFile = new File('latin1-data.txt')
def utf8File = new File('utf8-data.txt')
// Convert encoding
latinFile.withReader('ISO-8859-1') { reader ->
utf8File.withWriter('UTF-8') { writer ->
reader.copyTo(writer)
}
}
// Detect file encoding (requires external library)
def unknownFile = new File('unknown-encoding.txt')
// def detectedCharset = CharsetToolkit.guessEncoding(unknownFile)
// println "Detected encoding: $detectedCharset"
// Process multilingual text
def multilingualData = new File('multilingual.txt')
multilingualData.eachLine('UTF-8') { line ->
// Process Unicode text correctly
println "Line length: ${line.codePointCount(0, line.length())} characters"
}
// Text transformation pipeline
def inputFile = new File('input.txt')
def outputFile = new File('processed.txt')
inputFile.withReader('UTF-8') { reader ->
outputFile.withWriter('UTF-8') { writer ->
reader.eachLine { line ->
// Transform text: uppercase, trim, filter
def processed = line.trim().toUpperCase()
if (processed.length() > 0 && !processed.startsWith('#')) {
writer.println(processed)
}
}
}
}Handle network resources and URL-based I/O operations.
Usage Examples:
import java.net.URL
import java.net.URLConnection
// Read from URL
def url = new URL('https://api.example.com/data.json')
def jsonData = url.getText()
println "API Response: $jsonData"
// URL with custom headers
def connection = url.openConnection()
connection.setRequestProperty('User-Agent', 'Groovy Script')
connection.setRequestProperty('Accept', 'application/json')
def response = connection.inputStream.getText('UTF-8')
// Download file from URL
def fileUrl = new URL('https://example.com/document.pdf')
def localFile = new File('downloaded-document.pdf')
fileUrl.withInputStream { input ->
localFile.withOutputStream { output ->
input.copyTo(output)
}
}
// POST data to URL
def postUrl = new URL('https://api.example.com/submit')
def postConnection = postUrl.openConnection()
postConnection.doOutput = true
postConnection.requestMethod = 'POST'
postConnection.setRequestProperty('Content-Type', 'application/json')
def jsonPayload = '{"name": "John", "age": 30}'
postConnection.outputStream.withWriter('UTF-8') { writer ->
writer << jsonPayload
}
def statusCode = postConnection.responseCode
def responseText = postConnection.inputStream.getText('UTF-8')
println "Status: $statusCode, Response: $responseText"
// Error handling for network operations
try {
def unreliableUrl = new URL('https://unreliable-api.com/data')
def data = unreliableUrl.getText()
println "Success: $data"
} catch (IOException e) {
println "Network error: ${e.message}"
// Fallback to cached data or default values
}Monitor file system changes and respond to file modifications.
Usage Examples:
import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes
import static java.nio.file.StandardWatchEventKinds.*
// Simple file modification checking
def configFile = new File('config.properties')
def lastModified = configFile.lastModified()
// Periodically check for changes
def timer = new Timer()
timer.scheduleAtFixedRate(new TimerTask() {
void run() {
if (configFile.lastModified() > lastModified) {
println "Config file changed, reloading..."
// Reload configuration
lastModified = configFile.lastModified()
}
}
}, 0, 5000) // Check every 5 seconds
// Using Java NIO WatchService for real-time monitoring
def watchDir = Paths.get('.')
def watchService = FileSystems.getDefault().newWatchService()
watchDir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY)
// Monitor in separate thread
Thread.start {
while (true) {
def key = watchService.take()
for (event in key.pollEvents()) {
def kind = event.kind()
def filename = event.context()
println "File event: $kind - $filename"
if (kind == ENTRY_MODIFY && filename.toString().endsWith('.groovy')) {
println "Groovy file modified: $filename"
// Trigger recompilation or reload
}
}
if (!key.reset()) {
break
}
}
}
// File tree walking
def sourceDir = Paths.get('src')
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toString().endsWith('.groovy')) {
println "Found Groovy file: $file"
// Analyze or process file
}
return FileVisitResult.CONTINUE
}
FileVisitResult visitFileFailed(Path file, IOException exc) {
println "Failed to access: $file - ${exc.message}"
return FileVisitResult.CONTINUE
}
})/**
* Enhanced File operations (extension methods)
*/
interface FileExtensions {
/**
* Get file content as text with encoding
*/
String getText(String charset);
/**
* Set file content with encoding
*/
void setText(String text, String charset);
/**
* Process file lines with closure
*/
File eachLine(Closure closure);
File eachLine(String charset, Closure closure);
/**
* Safe resource processing
*/
Object withReader(Closure closure);
Object withWriter(Closure closure);
Object withInputStream(Closure closure);
Object withOutputStream(Closure closure);
/**
* Directory traversal methods
*/
void eachFile(Closure closure);
void eachFileRecurse(Closure closure);
void eachDir(Closure closure);
void eachDirRecurse(Closure closure);
/**
* Pattern-based file filtering
*/
void eachFileMatch(Object nameFilter, Closure closure);
void eachDirMatch(Object nameFilter, Closure closure);
}/**
* Enhanced stream operations (extension methods)
*/
interface StreamExtensions {
/**
* Get stream content as text
*/
String getText();
String getText(String charset);
/**
* Get stream content as bytes
*/
byte[] getBytes();
/**
* Copy stream content
*/
void copyTo(OutputStream target);
void copyTo(Writer target);
/**
* Process stream with closure
*/
Object withStream(Closure closure);
/**
* Line processing
*/
void eachLine(Closure closure);
void eachLine(String charset, Closure closure);
/**
* Line filtering
*/
void filterLines(Writer writer, Closure filter);
}
/**
* Writer extensions
*/
interface WriterExtensions {
/**
* Left shift operator for writing
*/
Writer leftShift(String text);
Writer leftShift(Object object);
/**
* Print methods
*/
void println(String text);
void println(Object object);
void printf(String format, Object... args);
}Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy