Skip to content

How-to Guides

Read and write Parquet files with Hardwood — pick the guide that matches what you need:

Runnable examples

Each guide below links to a matching standalone example in the hardwood-examples repository — every example is a complete project you can clone and run with a single command. New to Hardwood? Start with Hello Hardwood.

For detailed class-level documentation, see the JavaDoc.

Choosing a Reader

Hardwood provides two reader APIs:

  • RowReader — row-oriented access with typed getters, including nested structs, lists, and maps. Best for general-purpose reading where you process one row at a time.
  • ColumnReader — batch-oriented columnar access with typed primitive arrays. Best for analytical workloads where you process columns independently (e.g. summing a column, computing statistics).

For the reasoning behind the two APIs and the ergonomics-versus-throughput trade-off, see RowReader vs. ColumnReader.

Both support column projection and predicate pushdown. Each reader has a no-arg shortcut for default reads and a builder form for filtered or limited reads:

Reader Shortcut Builder
RowReader reader.rowReader() reader.buildRowReader().…build()
ColumnReader (single) reader.columnReader("id") reader.buildColumnReader("id").…build()
ColumnReaders (multiple) reader.columnReaders(projection) reader.buildColumnReaders(projection).…build()

To read multiple files as a single dataset with cross-file prefetching, open the ParquetFileReader with a list of InputFiles via the Hardwood class — see Reading Multiple Files.

Choosing a Writer

Writing mirrors the same split. Both APIs come from one ParquetFileWriter and produce the same layout, but a file is written through one of them, not both:

  • RowWriter — record-oriented, obtained from writer.rowWriter(). Fields are addressed by name, and logical-type values are written as the Java types the reader returns for them. Best when you hold records.
  • ColumnWriter — batch-oriented, obtained from writer.columnWriter(). Each writeBatch call takes one typed array per leaf column, plus per-layer validity and offsets for nested columns. Best when you already hold columns.

For the model behind the file the writer produces — why the footer comes last, what bounds memory, and how the encoding is chosen — see The Write Model.

For the exceptions the readers and the writer can throw and when, see Error Handling.