FileSystemProvider example....

Tom Lasseter t.lasseter at comcast.net
Tue Jun 26 22:49:49 PDT 2012


We can very easily use the existing  local FileSystemProvider to generate a
new local FileSystem rooted at an arbitrary point in the code below.

 

The somewhat bizarre "trick" here is using the USER_DIR property to set the
root location for the FileSystem ultimately provided:

 

System.setProperty(USER_DIR, partition + rootPathname + args[0]);  //
partition:  "driveLetter:", rootPathname: root for all FileSystems created,
arg[0]:  relative path to the root subdirectory desired

 

and then creating the new FileSystem:

 

uri = new URI("file", "", "/" , null);  // Anything other than "/" is NOT
ALLOWED (see checkURI(uri) method in WindowsFileSystemProvider)

FileSystemProvider fileSystemProvider =
FileSystemProvider.installedProviders().get(0); // assumption here is that
first one is the "default"

FileSystem fileSystem = fileSystemProvider.getFileSystem(uri);        

 

The output when you run the code below is:

 

User dir: G:/FileSystems/projectA

File path: \test.txt

Deleted file: \test.txt

Writing...

String written: Hello!

Reading...

String read: Hello!

 

I've tried everything else, but this is the only way I've found to use the
local FileSystemProvider to generate local FileSystem(s).  

 

Ideally, you would think you would not have to use this System.setProperty
hack and could provide the root path in the URI constructor above as:

 

uri = new URI("file", "", "g:/FileSystems/ProjectA" , null);

 

This doesn't work as the FileSystemProvider insists on having the URI
defined effectively as just "/" (above).  You almost might ask: "Why am I
being asked in the constructor to specify the URI if the only one it will
take is "/" ?  

 

Running on Windows, the WindowsFileSystemProvider is in package sun.nio.fs.
the newFileSystem and getFileSystem methods both call the checkURI method
which must return true for the FileSystem to be created/fetched:

 

private void checkUri(URI uri) 

{

           if (!uri.getScheme().equalsIgnoreCase(getScheme()))

               throw new IllegalArgumentException("URI does not match this
provider");

           if (uri.getAuthority() != null)

               throw new IllegalArgumentException("Authority component
present");

           if (uri.getPath() == null)

               throw new IllegalArgumentException("Path component is
undefined");

           if (!uri.getPath().equals("/"))

               throw new IllegalArgumentException("Path component should be
'/'");

           if (uri.getQuery() != null)

               throw new IllegalArgumentException("Query component
present");

           if (uri.getFragment() != null)

               throw new IllegalArgumentException("Fragment component
present");

}

 

So that:  if(!uri.getPath().equals("/")) you are hosed.  Thus you need to
set the root in some other sneaky fashion such as the USER_DIR trick above.


 

Seems like either (1) there is a more flexible constructor; or (2) there
isn't and the URI path argument should be removed from the constructor, and
thus the only allowed URI is "scheme:/"  where scheme must match the
provider. 

 

I'm SURE I must be missing something.  I can appreciate that if
FileSystem(s) are created but they are unknown effectively to the
defaultFileSystem, then they can't be created higgily-piggily (arcane
technical term).  So by forcing this very restrictive URI, we are limiting
where they actually can be created.  Seems like there should be a somewhat
less restrictive capability..which is why I'm sure that I am REALLY missing
something.   

 

Regards,

 

Tom

 

Code:

 

 

public class GcFileSystemProvider

{

               static public String partition = "G:/";

               static public String rootPathname = "FileSystems/";

 

               private static final String USER_DIR = "user.dir";

 

               GcFileSystemProvider()

               {

               }

 

               static public void main(String[] args)

               {

                              System.setProperty(USER_DIR, partition +
rootPathname + args[0]);

                              String userDir = System.getProperty(USER_DIR);

                              System.out.println("User dir: " + userDir);

                              URI uri = null;

                              Map<String, String> env = new HashMap<>();

                              env.put("create", "true");

                              FileSystem fileSystem = null;

                              FileSystemProvider fileSystemProvider = null;

                              try

                              {

                                             uri = new URI("file", "", "/" ,
null);

                                             fileSystemProvider =
FileSystemProvider.installedProviders().get(0); // assumption here is that
first one is the "standard"

                                             fileSystem =
fileSystemProvider.getFileSystem(uri);

                                             if(fileSystem == null)
fileSystem = fileSystemProvider.newFileSystem(uri, env);

                              }

                              catch(Exception e)

                              {

                                             e.printStackTrace();

                              }

 

                              Path path = fileSystem.getPath("/test.txt");

                              System.out.println("File path: " +
path.toString());

 

                              String text = "Hello!";

                              byte[] bytes = text.getBytes();

                              try

                              {

                                             if(Files.deleteIfExists(path))

 
System.out.println("Deleted file: " + path.toString());

 

                                             Set<OpenOption> writeOptions =
new HashSet<OpenOption>();

 
writeOptions.add(StandardOpenOption.CREATE);

 
writeOptions.add(StandardOpenOption.TRUNCATE_EXISTING);

 
writeOptions.add(StandardOpenOption.WRITE);

                                             Files.createFile(path);

                                             SeekableByteChannel
seekableByteChannel = fileSystemProvider.newByteChannel(path, writeOptions);

                                             ByteBuffer writeByteBuffer =
ByteBuffer.wrap(bytes);

 
System.out.println("Writing...");

                                             System.out.println("String
written: " + text);

 
seekableByteChannel.write(writeByteBuffer);

                                             seekableByteChannel.close();

                              }

                              catch(Exception e)

                              {

                                             e.printStackTrace();

                              }

                              System.out.println("Reading...");

 

                              try

                              {

                                             Set<OpenOption> readOptions =
new HashSet<OpenOption>();

 
readOptions.add(StandardOpenOption.READ);

                                             SeekableByteChannel
seekableReadByteChannel = fileSystemProvider.newByteChannel(path,
readOptions);

                                             ByteBuffer readByteBuffer =
ByteBuffer.allocate(100);

                                             int bytesRead =
seekableReadByteChannel.read(readByteBuffer);

                                             byte[] readBytes =
readByteBuffer.array();

                                             String readString = new
String(readBytes);

                                             System.out.println("String
read: " + readString);

                              }

                              catch (IOException e)

                              {

                                             e.printStackTrace();

                              }

               }

}

 

 

From: Tom Lasseter [mailto:t.lasseter at comcast.net] 
Sent: Monday, June 25, 2012 8:18 PM
To: nio-dev at openjdk.java.net
Subject: FileSystemProvider example....

 

 

 

The new Java 7 FileSystem is very cool..just what I need.but for the life of
me I can't create a custom FileSystemProvider.  There must be an example
somewhere!  There is only the ZipFileSystemProvider.  I want to create a new
FileSystem on either my local system or on a remote system.  

 

The simplest case is given the local system as the
DefaultFileSystemProvider, I want a new FileSystem from it rooted at some
arbitrary path, like c:/FileSystems/myFileSystem.  What could be easier than
that given the technology being provided.  I would think that this would do
it:

 

Map<String, String> env = new HashMap<>();

env.put("create", "true");

Path path = Paths.get("c:/FileSystems/myFileSystem");

FileSystem fileSystem = null;

try

{

fileSystem = fileSystemProvider.newFileSystem(path, env);

}

catch(Exception e)

{

               e.printStackTrace();

}

 

Help would be appreciated.  

 

Thanks and regards,

 

Tom

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20120626/f06f1efc/attachment-0001.html 


More information about the nio-dev mailing list