In the first section of this tutorial, we created a very simple Styx system which exposed a single file, an InMemoryFile that simply represented a section of RAM. Similarly, the FileOnDisk class is used to create a Styx file that represents a literal file on the local filesystem. The key to creating powerful distributed systems using Styx is to design and construct new types of virtual files that exhibit the correct behaviour.
In this section of the tutorial, you will learn how to create customized
virtual files. In essence, this simply involves creating a subclass of the
StyxFile class
and overriding key methods such as read() and write().
For our first example, let's create a file that, when read, will return the IP address and port number of the client that is making the connection. This file will therefore return data that is different for each client that is connected. This will be a read-only file. We'll call this class "WhoAmIFile". (See the full source code of the WhoAmIFile class, including full comments, here.)
As always, we need to subclass the StyxFile class:
public class WhoAmIFile extends StyxFile
public WhoAmIFile() throws StyxException
{
super("whoami");
this.setPermissions(0444);
}
r--r--r--).
Now we must override the read() method so that the IP address
and port are returned to the client. This is very easily done:
public void read(StyxFileClient client, long offset, int count, int tag)
throws StyxException
{
String clientAddr = client.getSession().getRemoteAddress().toString();
this.processAndReplyRead(clientAddr, client, offset, count, tag);
}
processAndReplyRead() to return
the data to the client.
In the above example, we used the processAndReplyRead() helper
method to process the read request and return the data to the client. This
is a very useful method that is used when the entire contents of a
file can be represented as a String, byte array or
ByteBuffer.
If the file cannot be represented in this way we have to work a little harder,
as we shall see in the example below. In this case, we have to work out
exactly what data we need to give to the client (based on the client's read
request and the contents of the whole file) and call one of the replyRead()
methods.