CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-nio

NIO extensions for Apache Groovy providing enhanced file system operations and path handling

Pending
Overview
Eval results
Files

object-serialization.mddocs/

Object Serialization

Handle Java object serialization and deserialization with support for custom class loaders and closure-based processing for safe resource management.

Capabilities

Object Output Stream Operations

Create and manage ObjectOutputStream objects for writing serializable objects to files.

/**
 * Create an object output stream for this path
 * @param self a Path object
 * @return an object output stream
 * @throws IOException if an IOException occurs
 */
ObjectOutputStream newObjectOutputStream(Path self);

/**
 * Create a new ObjectOutputStream for this path and then pass it to the closure.
 * This method ensures the stream is closed after the closure returns
 * @param self a Path
 * @param closure a closure
 * @return the value returned by the closure
 * @throws IOException if an IOException occurs
 */
<T> T withObjectOutputStream(Path self, Closure<T> closure);

Usage Examples:

import java.nio.file.Path
import java.nio.file.Paths

Path objectFile = Paths.get("data.ser")

// Create object output stream (manual resource management)
ObjectOutputStream objOut = objectFile.newObjectOutputStream()
try {
    objOut.writeObject("Hello, World!")
    objOut.writeObject(42)
    objOut.writeObject([1, 2, 3])
    objOut.flush()
} finally {
    objOut.close()
}

// Automatic resource management with closure
objectFile.withObjectOutputStream { objOut ->
    objOut.writeObject("String data")
    objOut.writeObject(new Date())
    objOut.writeObject([name: "John", age: 30])
    
    // Write multiple objects
    def people = [
        new Person("Alice", 25),
        new Person("Bob", 30),
        new Person("Charlie", 35)
    ]
    objOut.writeObject(people)
}

// Serialize custom objects
class Configuration implements Serializable {
    String hostname
    int port
    Map<String, String> properties
}

Path configFile = Paths.get("config.ser")
def config = new Configuration(
    hostname: "localhost",
    port: 8080,
    properties: [debug: "true", timeout: "30"]
)

configFile.withObjectOutputStream { objOut ->
    objOut.writeObject(config)
}

Object Input Stream Operations

Create and manage ObjectInputStream objects for reading serializable objects from files.

/**
 * Create an object input stream for this file
 * @param self a Path object
 * @return an object input stream
 * @throws IOException if an IOException occurs
 */
ObjectInputStream newObjectInputStream(Path self);

/**
 * Create an object input stream for this path using the given class loader
 * @param self a Path object
 * @param classLoader the class loader to use when loading the class
 * @return an object input stream
 * @throws IOException if an IOException occurs
 */
ObjectInputStream newObjectInputStream(Path self, ClassLoader classLoader);

/**
 * Create a new ObjectInputStream for this file and pass it to the closure.
 * This method ensures the stream is closed after the closure returns
 * @param path a Path
 * @param closure a closure
 * @return the value returned by the closure
 * @throws IOException if an IOException occurs
 */
<T> T withObjectInputStream(Path path, Closure<T> closure);

/**
 * Create a new ObjectInputStream for this file associated with the given class loader and pass it to the closure.
 * This method ensures the stream is closed after the closure returns
 * @param self a Path
 * @param classLoader the class loader to use when loading the class
 * @param closure a closure
 * @return the value returned by the closure
 * @throws IOException if an IOException occurs
 */
<T> T withObjectInputStream(Path self, ClassLoader classLoader, Closure<T> closure);

Usage Examples:

import java.nio.file.Path
import java.nio.file.Paths

Path objectFile = Paths.get("data.ser")

// Create object input stream (manual resource management)
ObjectInputStream objIn = objectFile.newObjectInputStream()
try {
    String stringData = objIn.readObject()
    Integer intData = objIn.readObject()
    List listData = objIn.readObject()
    
    println "String: ${stringData}"
    println "Integer: ${intData}"
    println "List: ${listData}"
} finally {
    objIn.close()
}

// Automatic resource management with closure
def objects = objectFile.withObjectInputStream { objIn ->
    def result = []
    try {
        while (true) {
            result << objIn.readObject()
        }
    } catch (EOFException e) {
        // Expected when reaching end of file
    }
    return result
}

println "Read ${objects.size()} objects: ${objects}"

// Deserialize with custom class loader
ClassLoader customLoader = new URLClassLoader([new File("custom-classes").toURI().toURL()] as URL[])

objectFile.withObjectInputStream(customLoader) { objIn ->
    def customObject = objIn.readObject()
    println "Loaded custom object: ${customObject}"
}

// Read configuration object
Path configFile = Paths.get("config.ser")
Configuration config = configFile.withObjectInputStream { objIn ->
    objIn.readObject() as Configuration
}

println "Loaded config: ${config.hostname}:${config.port}"
config.properties.each { key, value ->
    println "  ${key} = ${value}"
}

Object Iteration

Iterate through objects in a serialized file using closures.

/**
 * Iterates through the given file object by object
 * @param self a Path object
 * @param closure a closure
 * @throws IOException if an IOException occurs
 * @throws ClassNotFoundException if the class is not found
 */
void eachObject(Path self, Closure closure);

Usage Examples:

import java.nio.file.Path
import java.nio.file.Paths

Path objectFile = Paths.get("multiple-objects.ser")

// First, write multiple objects
objectFile.withObjectOutputStream { objOut ->
    objOut.writeObject("First object")
    objOut.writeObject(42)
    objOut.writeObject([name: "Alice", age: 25])
    objOut.writeObject(new Date())
    objOut.writeObject([1, 2, 3, 4, 5])
}

// Iterate through all objects in the file
objectFile.eachObject { obj ->
    println "Object type: ${obj.class.simpleName}, value: ${obj}"
}

// Process specific object types
objectFile.eachObject { obj ->
    switch (obj) {
        case String:
            println "Found string: '${obj}'"
            break
        case Number:
            println "Found number: ${obj} (${obj.class.simpleName})"
            break
        case List:
            println "Found list with ${obj.size()} elements: ${obj}"
            break
        case Map:
            println "Found map with keys: ${obj.keySet()}"
            break
        case Date:
            println "Found date: ${obj.format('yyyy-MM-dd HH:mm:ss')}"
            break
        default:
            println "Found other object: ${obj} (${obj.class.name})"
    }
}

// Count objects by type
def typeCounts = [:]
objectFile.eachObject { obj ->
    String typeName = obj.class.simpleName
    typeCounts[typeName] = (typeCounts[typeName] ?: 0) + 1
}

println "Object type summary:"
typeCounts.each { type, count ->
    println "  ${type}: ${count}"
}

// Filter and collect specific objects
def stringObjects = []
def numberObjects = []

objectFile.eachObject { obj ->
    if (obj instanceof String) {
        stringObjects << obj
    } else if (obj instanceof Number) {
        numberObjects << obj
    }
}

println "String objects: ${stringObjects}"
println "Number objects: ${numberObjects}"

Complex Serialization Examples

Advanced examples demonstrating real-world usage patterns.

Usage Examples:

import java.nio.file.Path
import java.nio.file.Paths

// Serialize application state
class ApplicationState implements Serializable {
    String version
    Map<String, Object> settings
    List<String> recentFiles
    Date lastSaved
}

Path stateFile = Paths.get("app-state.ser")

// Save application state
def currentState = new ApplicationState(
    version: "1.0.0",
    settings: [theme: "dark", language: "en", autoSave: true],
    recentFiles: ["/home/user/doc1.txt", "/home/user/doc2.txt"],
    lastSaved: new Date()
)

stateFile.withObjectOutputStream { objOut ->
    objOut.writeObject(currentState)
}

// Load application state
ApplicationState loadedState = stateFile.withObjectInputStream { objIn ->
    objIn.readObject() as ApplicationState
}

println "Loaded application state:"
println "  Version: ${loadedState.version}"
println "  Settings: ${loadedState.settings}"
println "  Recent files: ${loadedState.recentFiles}"
println "  Last saved: ${loadedState.lastSaved}"

// Serialize a cache of objects
Path cacheFile = Paths.get("object-cache.ser")

// Write cache
def cache = [
    "user:123": [id: 123, name: "Alice", email: "alice@example.com"],
    "user:456": [id: 456, name: "Bob", email: "bob@example.com"],
    "config:main": [timeout: 30, retries: 3, debug: false]
]

cacheFile.withObjectOutputStream { objOut ->
    cache.each { key, value ->
        objOut.writeObject([key: key, value: value])
    }
}

// Read cache
def loadedCache = [:]
cacheFile.eachObject { entry ->
    loadedCache[entry.key] = entry.value
}

println "Loaded cache entries:"
loadedCache.each { key, value ->
    println "  ${key}: ${value}"
}

// Serialize with versioning for backward compatibility
class VersionedData implements Serializable {
    private static final long serialVersionUID = 1L
    
    int version = 1
    String data
    Map<String, Object> metadata
    
    // Custom serialization for version handling
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject()
    }
    
    private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
        input.defaultReadObject()
        // Handle version-specific logic here
        if (version < 1) {
            // Upgrade old data format
            metadata = metadata ?: [:]
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-codehaus-groovy--groovy-nio

docs

directory-operations.md

file-appending.md

file-io.md

index.md

line-processing.md

object-serialization.md

stream-operations.md

tile.json