The following example demonstrates how better-files can be used to perform a complex sequence of operations: listing specific files, sorting them by size, skipping headers, distributing lines across multiple gzipped output files, and ensuring all resources are automatically closed.
Key features used in this example:
import better.files._ to access the API.- Path joining using the
/ operator (e.g., outputDir / s"part-$i.csv.gz"). list with a predicate to filter files (e.g., .extension == Some(".csv")).File.Order.bySize for sorting.lineIterator for memory-efficient line-by-line processing.newGzipOutputStream().printWriter() for compressed output..autoClosed to ensure resource safety in a for-comprehension.
import better.files._
def run(inputDir: File, outputDir: File, n: Int) = {
val count = new AtomicInteger()
val outputs = Vector.tabulate(n)(i => outputDir / s"part-$i.csv.gz")
for {
writers <- outputs.map(_.newGzipOutputStream().printWriter()).autoClosed
inputFile <- inputDir.list(_.extension == Some(".csv")).toSeq.sorted(File.Order.bySize)
line <- inputFile.lineIterator.drop(1)
} writers(count.incrementAndGet() % n).println(line)
}