As noted in the previous section, in general to make a
StarTable
you need to supply the location of a resource
which can supply the table data stream more than once, since it may be
necessary to make multiple passes. In some cases however, depending
on the format-specific handler being used, it is possible to read
a table from a non-rewindable stream such as System.in
.
In particular both the FITS and VOTable input handlers permit this.
The most straightforward way of doing this is to use the
StarTableFactory
's
makeStarTable(InputStream,TableBuilder)
method.
The following snippet reads a FITS table from standard input:
return new StarTableFactory().makeStarTable( System.in, new FitsTableBuilder() );caching the table data as determined by the default storage policy (see Section 4).
It is possible to exercise more flexibility however if you
don't need a stored StarTable
object as the result of
the read. If you just want to examine the table data as it comes
through the stream rather than to store it for later use, you can
implement a TableSink
object
which will be messaged with the input table's metadata and data as
they are encountered, and pass it to the
streamStarTable
method of a suitable TableBuilder
.
This of course is cheaper on resources than
storing the data. The following code prints the name of the
first column and the average of its values (assumed numerical):
// Set up a class to handle table processing callback events. class ColumnReader implements TableSink { private long count; // number of rows so far private double sum; // running total of values from first column // Handle metadata by printing out the first column name. public void acceptMetadata( StarTable meta ) { String title = meta.getColumnInfo( 0 ).getName(); System.out.println( "Title: " + title ); } // Handle a row by updating running totals. public void acceptRow( Object[] row ) { sum += ((Number) row[ 0 ]).doubleValue(); count++; } // At end-of-table event calculate and print the average. public void endRows() { double average = sum / count; System.out.println( "Average: " + average ); } }; // Streams the named file to the sink we have defined, getting the data // from the first TABLE element in the file. public void summarizeFirstColumn( InputStream in ) throws IOException { ColumnReader reader = new ColumnReader(); new VOTableBuilder().streamStarTable( in, reader, "0" ); in.close(); }Again, this only works with a table input handler which is capable of streamed input.
Writing multiple tables to the same place (for instance, to multiple
extensions of the same multi-extension FITS file) works in a similar way,
but you use instead one of the writeStarTables
methods
of StarTableOutput
. These take an array of tables rather
than a single one.