FileSystemProvider example....

Alan Bateman Alan.Bateman at oracle.com
Tue Jun 26 23:55:54 PDT 2012


Tom - I don't have time to send a detailed reply now but the user.dir 
property is used by the default provider in order to determine the 
working directory, it's not the root. The default provider does not 
support a way to prevent someone "escaping" to other areas of the file 
system and I think, as per my first reply, that you'll need to create 
another provider that layers over the default provider to do that. On 
the URI business then this is because the default provider is a 
singleton, it's not meant to be instantiated with different URIs. The 
normal way to get a reference to it is via FileSystems.getDefault().

-Alan.

On 27/06/2012 06:49, Tom Lasseter wrote:
>
> 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/20120627/5b7cba9a/attachment-0001.html 


More information about the nio-dev mailing list