9 Streams

Streams provide flexible access to GAP's input and output processing. An input stream takes characters from some source and delivers them to GAP which reads them from the stream. When an input stream has delivered all characters it is at end-of-stream. An output stream receives characters from GAP which writes them to the stream, and delivers them to some destination.

A major use of streams is to provide efficient and flexible access to files. Files can be read and written using Read and AppendTo, however the former only allows a complete file to be read as GAP input and the latter imposes a high time penalty if many small pieces of output are written to a large file. Streams allow input files in other formats to be read and processed, and files to be built up efficiently from small pieces of output. Streams may also be used for other purposes, for example to read from and print to GAP strings, or to read input directly from the user.

Any stream is either a text stream, which translates the end-of-line character ('\n') to or from the system's representation of end-of-line (e.g., new-line under UNIX, carriage-return under MacOS, carriage-return-new-line under DOS), or a binary stream, which does not translate the end-of-line character. The processing of other unprintable characters by text streams is undefined. Binary streams pass them unchanged.

Note that binary streams are @not yet implemented@.

Whereas it is cheap to append to a stream, streams do consume system resources, and only a limited number can be open at any time, therefore it is necessary to close a stream as soon as possible using CloseStream described in Section CloseStream. If creating a stream failed then LastSystemError (see LastSystemError) can be used to get information about the failure.

Sections

  1. Categories for Streams and the StreamsFamily
  2. Operations applicable to All Streams
  3. Operations for Input Streams
  4. Operations for Output Streams
  5. File Streams
  6. User Streams
  7. String Streams
  8. Dummy Streams

9.1 Categories for Streams and the StreamsFamily

  • IsStream C

    Streams are GAP objects and all open streams, input, output, text and binary, lie in this category.

  • IsClosedStream C

    When a stream is closed, its type changes to lie in 'IsClosedStream'. This category is used to install methods that trap accesses to closed streams.

  • IsInputStream C

    All input streams lie in this category, and support input operations such as ReadByte (see Operations for Input Streams)

  • IsInputTextStream C

    All text input streams lie in this category. They translate new-line characters read.

  • IsInputTextNone C

    It is convenient to use a category to distinguish dummy streams (see Dummy Streams) from others. Other distinctions are usually made using representations

  • IsOutputStream C

    All output streams lie in this category and support basic operations such as WriteByte (see Operations for Output Streams)

  • IsOutputTextStream C

    All text output streams lie in this category and translate new-line characters on output.

  • IsOutputTextNone C

    It is convenient to use a category to distinguish dummy streams (see Dummy Streams) from others. Other distinctions are usually made using representations

  • StreamsFamily V

    All streams lie in the StreamsFamily

    9.2 Operations applicable to All Streams

  • CloseStream( stream ) O

    In order to preserve system resources and to flush output streams every stream should be closed as soon as it is no longer used using CloseStream.

    It is an error to try to read characters from or write characters to a closed stream. Closing a stream tells the GAP kernel and/or the operating system kernel that the file is no longer needed. This may be necessary because the GAP kernel and/or the operating system may impose a limit on how many streams may be open simultaneously.

    9.3 Operations for Input Streams

    Three operations normally used to read files: Read, ReadAsFunction and ReadTest can also be used to read GAP input from a stream. The input is immediately parsed and executed. When reading from a stream str, the GAP kernel generates calls to ReadLine(str) to supply text to the parser.

    Three further operations: ReadByte, ReadLine and ReadAll, support reading characters from an input stream without parsing them. This can be used to read data in any format and process it in GAP.

    Additional operations for input streams support detection of end of stream, and (for those streams for which it is appropriate) random access to the data.

  • Read( input-text-stream )

    reads the input-text-stream as input until end-of-stream occurs. See File Operations for details.

  • ReadAsFunction( input-text-stream )

    reads the input-text-stream as function and returns this function. See File Operations for details.

  • ReadTest( input-text-stream )

    reads the input-text-stream as test input until end-of-stream occurs. See File Operations for details.

    Example

    # as function with local `a' does not change the global one
    gap> a := 1;;
    gap> i := InputTextString( "local a; a := 10; return a*10;" );;
    gap> ReadAsFunction(i)();
    100
    gap> a;
    1
    
    # reading it via `Read' does
    gap> i := InputTextString( "a := 10;" );;                      
    gap> Read(i);
    gap> a;
    10
    

  • ReadByte( input-stream ) O

    ReadByte returns one character (returned as integer) from the input stream stream-in. ReadByte returns fail if there is no character available, in particular if it is at the end of a file.

    If stream-in is the input stream of a input/output process, ReadByte may also return fail if the process is also trying to read.

    ReadByte is the basic operation for input streams. If a ReadByte method is installed for a user-defined type of stream, then all the other input stream operations will work (although possibly not at peak efficiency).

  • ReadLine( input-text-stream ) O

    ReadLine returns one line (returned as string with the newline) from the input stream stream-in. ReadLine reads in the input until a newline is read or the end-of-stream. is encountered.

    If stream-in is the input stream of a input/output process, ReadLine may also return fail if the process is also trying to read. Such processes are @not yet implemented@

    A default method is supplied for ReadLine which simply calls ReadByte repeatedly. The kernel uses calls to ReadLine to supply input to the parser when reading from a stream.

  • ReadAll( input-text-stream ) O

    ReadAll returns all characters as string from the input stream stream-in. It reads in the input until the stream is at end-of-stream, it returns fail if the input-text-stream is already at the end-of-stream.

    If stream-in is the input stream of a input/output process, ReadAll may also return fail if the process is also trying to read. @input/output processes are not yet implemented@.

    A default method is supplied for ReadAll which simply calls ReadByte repeatedly.

    Example

    gap> i := InputTextString( "1Hallo\nYou\n1" );;
    gap> ReadByte(i);
    49
    gap> CHAR_INT(last);
    '1'
    gap> ReadLine(i);
    "Hallo\n"
    gap> ReadLine(i);
    "You\n"
    gap> ReadLine(i);
    "1"
    gap> ReadLine(i);
    fail
    gap> ReadAll(i);
    ""
    gap> RewindStream(i);;
    gap> ReadAll(i);     
    "1Hallo\nYou\n1"
    

  • IsEndOfStream( input-stream ) O

    IsEndOfStream returns true if the input stream is at end-of-stream, and false otherwise. Note that IsEndOfStream might return false even if the next ReadByte fails.

  • PositionStream( input-stream ) O

    Some input streams, such as string streams and file streams attached to disk files, support a form of random access by way of the operations PositionStream, SeekPositionStream and RewindStream. PositionStream returns a non-negative integer denoting the current position in the stream (usually the number of characters before the next one to be read.

    If this is not possible, for example for an input stream attached to standard input (normally the keyboard), then fail is returned

  • RewindStream( input-stream ) O

    RewindStream attempts to return an input stream to its starting condition, so that all the same characters can be read again. It returns true if the rewind succeeds and fail otherwise

    A default method implements RewindStream using SeekPositionStream.

  • SeekPositionStream( input-stream, pos ) O

    SeekPositionStream attempts to rewind or wind forward an input stream to the specified position. This is not possible for all streams. It returns true if the seek is successful and fail otherwise.

    9.4 Operations for Output Streams

  • WriteByte( output-stream, byte ) O

    writes the next character (given as integer) to the output stream output-stream. The function returns true if the write succeeds and fail otherwise.

    WriteByte is the basic operation for input streams. If a WriteByte method is installed for a user-defined type of stream, then all the other output stream operations will work (although possibly not at peak efficiency).

  • WriteLine( output-text-stream, string ) O

    appends string to output-stream. A final newline is written. The function returns true if the write succeeds and fail otherwise.

    A default method is installed which implements WriteLine by repreated calls to WriteByte.

  • WriteAll( output-text-stream, string ) O

    appends string to output-stream. No final newline is written. The function returns true if the write succeeds and fail otherwise.

    A default method is installed which implements WriteAll by repreated calls to WriteByte.

    When Printing or appending to a stream (using PrintTo, or AppendTo or when logging to a stream), the kernel generates a call to WriteAll for each line output.

    Example

    gap> str := "";; a := OutputTextString(str,true);;
    gap> WriteByte(a,INT_CHAR('H'));
    true
    gap> WriteLine(a,"allo");
    true
    gap> WriteAll(a,"You\n");
    true
    gap> CloseStream(a);
    gap> Print(str);
    Hallo
    You
    

  • PrintTo( output-stream, arg1, ... )
  • AppendTo( output-stream, arg1, ... )

    These functions work like Print, except that the output is appended to the output stream output-stream.

    Example

    gap> str := "";; a := OutputTextString(str,true);;
    gap> AppendTo( a, (1,2,3), ":", Z(3) );
    gap> CloseStream(a);
    gap> Print( str, "\n" );
    (1,2,3):Z(3)
    

  • LogTo( stream ) F

    LogTo may be used with a stream, just as with a file. See File Operations for details

  • InputLogTo( stream ) O

    InputLogTo may be used with a stream, just as with a file. See File Operations for details

  • OutputLogTo( stream ) O

    OutputLogTo may be used with a stream, just as with a file. See File Operations for details

    When text is being sent to an output text stream via PrintTo, AppendTo, LogTo, etc., it is, by default formatted just as it would be were it being printed to the screen. Thus, it is broken into lines of reasonable length at (where possible) sensible places, lines containing elements of lists or records are indented, and so forth. This is appropriate if the output is eventually to be viewed by a human, and harmless if it to passed as input to GAP, but may be unhelpful if the output is to be passed as input to another program. It is possible to turn off this behaviour for a stream using the SetPrintFormattingStatus operation, and to test whether it is on or off using PrintFormattingStatus.

  • SetPrintFormattingStatus( stream, newstatus ) O

    SetPrintFormattingStatus( stream, newstatus ) sets whether output sent to the stream via PrintTo, AppendTo, etc. (but not WriteByte, WriteLine or WriteAll) will be formatted with line breaks and indentation. If the second argument is true then output will be so formatted, if false then it will not.

  • PrintFormattingStatus( stream ) O

    PrintFormattingStatus( stream ) returns 'true' if output sent to the stream via PrintTo, AppendTo, etc. (but not WriteByte, WriteLine or WriteAll) will be formatted with line breaks and indentation, and false otherwise.

    Example

    gap> s := "";; str := OutputTextString(s,false);;                              
    gap> PrintTo(str,Primes{[1..30]});                                             
    gap> s;
    "[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\
     \n  73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ]"
    gap> Print(s,"\n");
    [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 
      73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ]
    gap> SetPrintFormattingStatus(str, false);
    gap> PrintTo(str,Primes{[1..30]});
    gap> s;
    "[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\
     \n  73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ][ 2, 3, 5, 7, 11, 13, 17, 19\
    , 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103\
    , 107, 109, 113 ]"
    gap> Print(s,"\n");
    [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 
      73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ][ 2, 3, 5, 7, 11, 13, 17, 19, 2\
    3, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 1\
    07, 109, 113 ]
    gap> 
    

    9.5 File Streams

    File streams are streams associated with files. An input file stream reads the characters it delivers from a file, an output file stream prints the characters it receives to a file. The following functions can be used to create such streams. They return fail if an error occurred, in this case LastSystemError (see LastSystemError) can be used to get information about the error.

  • InputTextFile( name-file ) O

    InputTextFile( name-file ) returns an input stream in the category IsInputTextStream that delivers the characters from the file name-file.

  • OutputTextFile( name-file, append ) O

    OutputTextFile( name-file, append ) returns an output stream in the category IsOutputTextFile that writes received characters to the file name-file. If append is false, then the file is emptied first, otherwise received characters are added at the end of the list.

    Example

    # use a temporary directory
    gap> name := Filename( DirectoryTemporary(), "test" );;
    
    # create an output stream, append output, and close again
    gap> output := OutputTextFile( name, true );;
    gap> AppendTo( output, "Hallo\n", "You\n" );
    gap> CloseStream(output);
    
    # create an input, print complete contents of file, and close
    gap> input := InputTextFile(name);;
    gap> Print( ReadAll(input) );
    Hallo
    You
    gap> CloseStream(input);
    
    # append a single line
    gap> output := OutputTextFile( name, true );; 
    gap> AppendTo( output, "AppendLine\n" );
    
    # close output stream to flush the output
    gap> CloseStream(output);
    
    
    # create an input, print complete contents of file, and close
    gap> input := InputTextFile(name);;
    gap> Print( ReadAll(input) );
    Hallo
    You
    AppendLine
    gap> CloseStream(input);
    

    9.6 User Streams

    The following two commands create streams which accept characters from, or deliver characters to, the user, via the keyboard or the GAP session display.

  • InputTextUser( ) F

    returns an input text stream which delivers characters typed by the user (or from the standard input device if it has been redirected). In normal circumstances, characters are delivered one by one as they are typed, without waiting until the end of a line. No prompts are printed.

  • OutputTextUser( ) F

    returns an output stream which delivers characters to the user's display (or the standard output device if it has been redirected). Each character is delivered immediately it is written, without waiting for a full line of output. Text written in this way is not written to the session log (see LogTo).

    9.7 String Streams

    String streams are streams associated with strings. An input string stream reads the characters it delivers from a string, an output string stream appends the characters it receives to a string. The following functions can be used to create such streams.

  • InputTextString( string ) O

    InputTextString( string )returns an input stream that delivers the characters from the string string. The string is not changed when reading characters from it and changing the string after the call to InputTextString has no influence on the input stream.

  • OutputTextString( list, append ) O

    returns an output stream that puts all received characters into the list list. If append is false, then the list is emptied first, otherwise received characters are added at the end of the list.

    Example

    # read input from a string
    gap> input := InputTextString( "Hallo\nYou\n" );;
    gap> ReadLine(input);
    "Hallo\n"
    gap> ReadLine(input);
    "You\n"
    
    # print to a string
    gap> str := "";;
    gap> out := OutputTextString( str, true );;
    gap> PrintTo( out, 1, "\n", (1,2,3,4)(5,6), "\n" );
    gap> CloseStream(out);
    gap> Print( str );
    1
    (1,2,3,4)(5,6)
    

    9.8 Dummy Streams

    The following two commands create dummy streams which will consume all characters and never deliver one.

  • InputTextNone( ) F

    returns a dummy input text stream, which delivers no characters, i.e., it is always at end of stream. Its main use is for calls to Process (see Process) when the started program does not read anything.

  • OutputTextNone( ) F

    returns a dummy output stream, which discards all received characters. ts main use is for calls to Process when the started program does not write anything.

    [Top] [Previous] [Up] [Next] [Index]

    GAP 4 manual
    July 1999