exebook
exebook

Reputation: 33900

Read entire file contents as a string

How do you read the entire file contents into a string variable in Genie?

(I cannot find anything in docs. The docs also seem scattered and incomplete.)

Upvotes: 3

Views: 288

Answers (1)

AlThomas
AlThomas

Reputation: 4289

The Genie language itself does not have file input/output built in. You will need to use a library and that is partly why the documentation is in a lot of places. There is a lot of choice!

As a general rule, a good starting place for low-level functionality like this is the GLib library. Genie makes heavy use of GLib for its type system and includes the bindings to the GLib library by default. So here is an example using GLib's FileUtils:

[indent=4]
init
    var filename = "test.txt"
    file_loaded:bool = false
    contents_of_file:string
    try
         file_loaded = FileUtils.get_contents( filename, out contents_of_file )
    except error:FileError
        print( error.message )
    if file_loaded
         print( @"Contents of $filename:

$contents_of_file")

Compile with:

valac fileutils_example.gs

This example makes use of Genie's:

  • type inference with the var keywod
  • an out parameter contents_of_file
  • scoping rules by declaring contents_of_file outside the try...except block
  • string templates, the @"" syntax for calling a variable's to_string() method

The GLib library contains an additional component, GIO, that provides asynchronous input/output and a streams based API. The next example is a very basic example that does the same as above, but using the GIO interfaces:

[indent=4]
init
    var file = File.new_for_path( "test.txt" )
    file_loaded:bool = false
    contents_of_file:array of uint8
    try
        file_loaded = file.load_contents( null, out contents_of_file, null )
    except error:Error
        print( error.message )
    if file_loaded
        text:string = (string)contents_of_file
        print( @"Contents of $(file.get_basename()):

$text")

Compile with:

valac --pkg gio-2.0 -X -w fileinputstream_example.gs

Points to note are:

  • --pkg gio-2.0 uses the GIO library, --pkg glib-2.0 was not needed in the earlier example because that is done by default
  • contents_of_file:array of uint8 is a buffer and an out parameter for load_contents ()
  • the -X -w option to valac suppresses the warning from the C compiler that guint8 is being passed when it was expecting char
  • the buffer needs to be cast to a string: (string)contents_of_file
  • if you are using a GLib.Mainloop or a derived loop, you could get GIO to load the file in a background thread: file_loaded = yield file.load_contents_async( null, out contents_of_file, null )
  • if you get to the point of writing a binding to a library then the null arguments could have been given default values of null so they become optional, but that technique was not used in the GIO bindings

Finally, there may other libraries that better fit your needs. For example Posix.FILE is another way of reading and writing files.

Upvotes: 4

Related Questions