WebNFS Developer's Guide

Chapter 2 Extended Filesystem API

Network computer vendors have realized that network file systems can add a powerful capability to their products. Experienced Java application developers want access to all the files the Internet has to offer in the same way. To meet this demand, several vendors are working on distributed file systems, such as WebNFS, CIFS, and others.

This chapter describes the Extended Filesystem API (XFile API). The Extended Filesystem API provides a common interface for multiple filesystem types. Also, it allows dynamic loading of filesystem implementations. The API includes a set of classes similar to those in the java.io API, and therefore provides a familiar programmatic means of accessing files, either locally or remotely. The API also provides a means to access file- and filesystem-specific information.

Features

The Extended Filesystem model:

Overview

The extended filesystem provides extensibility through the use of:

The API defines two means of access to network files and filesystems:

The API supports three categories of applications:

Architecture

The following picture shows the extended filesystem architecture. The XFile (com.sun.xfile.*) layer of the architecture mirrors the standard java.io.File* programmatic interfaces. Under this layer is a set of XFileAccessors. There is one XFileAccessor interface implementation for each filesystem being supported. (Currently only NFS and native filesystems are supported.) The accessors implement the XFileAccessor interface. They are responsible for all aspects of file access. The API classes are responsible for multiplexing between the different filesystems as requests are made from the application.

Table 2-1 Extended Filesystem Architecture

Java Application 

com.sun.xfile.*
 nfs: cifs: file: native:

The WebNFS SDK includes support for dynamic loading of file systems. Please see Chapter 4, The XFileAccessor Interface Class and Methods.

URL Naming

Every filesystem type is identified by a URL of the general form described in RFC 1738 (ftp://ftp.isi.edu/in-notes/rfc/1738.txt). The extended filesystem uses the scheme name in the URL to automatically select a filesystem. For example, the NFS filesystem has the scheme name of "nfs." When presented with a filename string, the extended filesystem checks for a URL scheme followed by a colon at the beginning of the string. If it finds one, it uses the filesystem accessor class associated with that URL scheme. If it does not find one, it defaults to the "native" scheme for access through java.io.*.

URL Names and Native Names

Filenames are assumed to be absolute URLs or relative URLs as determined by a context. If a filename string begins with a valid URL scheme name followed by a colon, then the name is associated with the filesystem type indicated by the URL scheme name. For instance, a filename string of the form nfs://hostname/path is associated with the filesystem that has the scheme name of nfs. If the filename has no colon-separated prefix, or the scheme is not recognized then the name is assumed to belong to the default "native" scheme, that is, a URL prefix of native: is assumed and the name is handled by java.io.*. The two-argument constructor for XFile takes an XFile object and a filename:


XFile(Xfile dir, String filename)

The filename argument is interpreted according to the context set by the dir argument. The dir argument is used as a base URL and the name is evaluated as a relative URL. If the filename is an absolute URL, then the dir is ignored. If the filename is a relative URL, then it is combined with the base URL to form the name of the new XFile object. The rules that describe the evaluation of relative URLs are described in RFC 1808 (ftp://ftp.isi.edu/in-notes/rfc1808.txt).

Filesystem Selection

Filesystems are selected using these rules:

  1. If the XFile(String filename) constructor is used and the filename has a prepended URL scheme, the filesystem associated with that scheme is used; otherwise, the native filesystem is used.

  2. If the XFile(XFile dir, String filename) constructor is used, the filename is evaluated as a relative URL to the dir XFile.

Examples of File Name Usage and Filesystem Selection

The following examples show how the XFile constructors may be used:

XFile f1 = new XFile("nfs://hostname/directory1");

// NFS file based on an absolute URL

XFile f2 = new XFile("file.txt");

// not a URL, so defaults to the current directory of the "native" filesystem

XFile f4 = new XFile(f1,"text.html");

// evaluated relative to the base URL of f1 - which is "nfs".

One point to be made from these examples is that the validity of a constructed XFile is made when the XFile is used, not when it is constructed. This is consistent with the java.io.File class.

Direct Access to Filesystem-Specific Features

A reference to the object implementing a filesystem's specific features can be determined through the class interface. The interface allows developers to directly call these methods. By doing this, you are increasing the risk of writing code that works only for one filesystem type, so its use is discouraged. To obtain access to these features directly, use the public method XFile.getExtensionAccessor(). Once you have obtained this handle, you can access its methods directly. Refer to the filesystem implementor's documentation for class description details.

The following example shows how a method in the NFS XFileExtensionAccessor is used to set the user's authentication credentials using the NFS PCNFSD protocol:


Example 2-1 Using an NFS XFileExtensionAccessor

import java.io.*;
import com.sun.xfile.*;
import com.sun.nfs.*;

public class nfslogin {

     public static void main(String av[])
     {
          try {
               XFile xf = new XFile(av[0]);
               com.sun.nfsXFileExtensionAccessor nfsx =
               (com.sun.nfsXFileExtensionAccessor) xf.getExtensionAccessor();

               if (! nfsx.loginPCNFSD("pcnfsdsrv", "bob", "-passwd-")) {
                    System.out.println("login failed");
                    return;
               }

               if (xf.canRead())
                    System.out.println("Read permission OK");
               else
                    System.out.println("No Read permission");

          } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace(System.out);
          }
     }
}

Class Descriptions

This section describes the additional methods that are not currently part of the java.io classes. For example, the first entry, called XFile, describes the methods that are in the com.sun.xfile.XFile class but not in the java.io.File class. All com.sun.xfile classes that have a counterpart in the java.io classes are generally a superset of the java.io classes in the methods provided, not including constructors. File descriptors are not supported and constructors that use a java.io.File* class now use a com.sun.xfile.XFile* class. Also shown are the few new interfaces and classes defined by the extended filesystem. A complete description of the API can be found in the XFile javadoc files included in the release.

Table 2-2 XFile Classes

Classes 

java.io.File Equivalent

Methods 

XFile

java.io.File

public XFile(String url) - class constructor public XFile(XFile dir, String relurl) - class constructor

XFileOutputStream

FileOutputStream

public XFileOutputStream(XFile file) - class constructor

XFileInputStream

FileInputStream

public XFileInputStream(XFile file) - class constructor

XRandomAccessFile

RandomAccessFile

public XRandomAccessFile(XFile file, String mode) -class constructor

XFilenameFilter

FilenameFilter

public abstract boolean accept(XFile dir, String name) - filter based on file spec

XFileReader

FileReader

XFileReader(XFile file)

XFileWriter

FileWriter

XFileWriter(XFile file, String access)

File Interface Examples

Extending existing programs to network filesystems should be straightforward using the extensions provided. You simply replace declarations of type java.io.FileXYZ with the counterpart java.io.XFileXYZ. Here are a few simple examples of applications that use the APIs:


Example 2-2 Using Streams Interface

import java.io.*;
import java.net.*;
import com.sun.xfile.*;

XFile xf = new XFile("file.txt");

if (xf.isFile()) {
     System.out.println("file is file");
}

if (xf.isDirectory()) {
     System.out.println("file is directory");
}

XFileInputStream nfis = null;
nfis = new XFileInputStream(xf);

for (int count = 0; ; count++) {
     int val = (byte) nfis.read();
     if (val == -1)
          break;
     System.out.write(val);
}

System.out.println("read " + count + " bytes ");


Example 2-3 Using the XRandomAccessFile Interface

import java.io.*;
import java.net.*;
import com.sun.xfile.*;

     // create connection to host

XFile xf = new XFile("nfs://ian/simple.html");

XRandomAccessFile xraf = new XRandomAccessFile(xf,"r");

int count = 10;

xraf.seek(count);
System.out.println("Value at position " + count
     + " is " + (byte)xraf.read());

System.out.println("Current file position is "
     + xraf.getFilePointer());

xraf.seek(0);

for (count = 0 ; count < 100 ; count++) {
     int val = xraf.read();
     if (val == -1)
          break;
     System.out.print(val);
}