Time for action – accessing files

Let's see how it works:

  1. Let's create a new script called core-files.js, and fill it with these lines:
    #!/usr/bin/env seed
    
    GLib = imports.gi.GLib;
    Gio = imports.gi.Gio;
    GObject = imports.gi.GObject;
    
    Main = new GType({
      parent: GObject.Object.type,
      name: "Main",
      init: function(self) {      
        this.start = function() {
          var file = null;
          var files = ["http://en.wikipedia.org/wiki/Text_file", "core-files.js"];
    
          for (var i = 0; i < files.length; i++) {
            if (files[i].match(/^http:/)) {
              file = Gio.file_new_for_uri(files[i]);
            } else {
              file = Gio.file_new_for_path(files[i]);
            }
    
            var stream = file.read();
            var data_stream = new Gio.DataInputStream.c_new(stream);
              var data = data_stream.read_until("", 0);
    
              Seed.print(data)          
          }
        }  
      }
    });
    
    var main = new Main();
    main.start();
  2. Alternatively, you can create a Vala project called core-files. Fill src/core_files.vala with this code:
    using GLib;
    
    public class Main : Object
    {
      public Main ()
      {
      }
    
      public void start ()
      {
        File file = null;
        string[] files = {"http://en.wikipedia.org/wiki/Text_file", "src/core_files.vala"};
     
        for (var i = 0; i < files.length; i++) {
          if (files[i].has_prefix("http:")) {
            file = File.new_for_uri(files[i]);
          } else {
            file = File.new_for_path(files[i]);
          }
    
          var stream = file.read();
          var data_stream = new DataInputStream(stream);
          size_t data_read;
            var data = data_stream.read_until("", out data_read);
            stdout.printf(data);
        }
      }
    
      static int main (string[] args)
      {
        var app = new Main ();
        app.start();
        return 0;
      }
    }
  3. Run the program, and notice that it fetches the Wikipedia page from the Internet as well as the source code of the program from the local directory.
    Time for action – accessing files

GIO aims to provide a set of powerful virtual filesystem APIs. It provides a set of interfaces that serve as a foundation to be extended by the specific implementation. For example, here we use the GFile interface that defines the functions for a file. The GFile API does not tell us where the file is located, how the file is read, or other such details. It just provides the functions and that's it. The specific implementation that is transparent to the application developers will do all the hard work. Let's see what this means.

In the following code, we get the file location from the array files. Then we check if the location has an HTTP protocol identifier or not; if yes, we create the GFile object using file_new_for_uri, otherwise we use file_new_for_path. We can, of course, use file_new_for_uri even for the local file, but we need to prepend the file:// protocol identifier to the filename.

This is the only difference between handling the remote file and the local file. And after that we can access files either from the local drive or from a web server by using the same function with GIO.

Here we use the read function to get the GFileInputStream object. Notice here that the API provides the same function wherever the file is.

The resulting object is a stream. A stream is a sequence of data that flows from one end to the other. The stream can be passed to an object and can transform it to become another stream or just consume it.

In our case, we get the stream initially from the file.read function. We transfer this stream into GDataInputStream in order to easily read the data. With the new stream, we ask GIO to read the data until we find nothing, which means it has reached the end of the file. And then we spit the data out onto the screen.