Next Previous Up Contents
Next: Generic Table Output
Up: Table I/O
Previous: Generic Table Resource Input

### 3.3 Generic Table Streamed Input

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.

Next Previous Up Contents
Next: Generic Table Output
Up: Table I/O
Previous: Generic Table Resource Input

STIL - Starlink Tables Infrastructure Library
Starlink User Note252
STIL web page: http://www.starlink.ac.uk/stil/
Author email: m.b.taylor@bristol.ac.uk