Let's see how it works:
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();
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; } }
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.
if (files[i].match(/^http:/)) { file = Gio.file_new_for_uri(files[i]); } else { file = Gio.file_new_for_path(files[i]); }
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.
var stream = file.read(); var data_stream = new Gio.DataInputStream.c_new(stream); var data = data_stream.read_until("", 0);
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.