简体   繁体   中英

Commons VFS and Java.net.URL - Adding support for “ram://” protocol

I'm using commons-vfs and for my tests I want to use a ram file system. When I try with new URL("ram:///A/B/sample.jar") I get the following exception:

java.net.MalformedURLException: unknown protocol: ram
    at java.net.URL.<init>(URL.java:592)
    at java.net.URL.<init>(URL.java:482)
    at java.net.URL.<init>(URL.java:431)

Here is some code (when I use file protocol everything works fine)

// URL is used to construct an object
obj.addArchive(new URL("ram:///A/B/sample.jar"))    
...
// then VFS is used to scan the object urls
// for instance get the parent directory
FileSystemManager manager = VFS.getManager();
String directory = manager.resolveFile(obj.getPath()).getParent().getURL().toExternalForm();

How I could use ram protocol in java.net.URL ?

I've found a solution based on the use of custom URL handlers as described here .

Add a maven dependency to url-scheme-registry :

<dependency>
    <groupId>org.skife.url</groupId>
    <artifactId>url-scheme-registry</artifactId>
    <version>0.0.1</version>
</dependency>

Create a custom URLStreamHandler for the ram schema:

public class RamHandler extends URLStreamHandler { 
  @Override
  protected URLConnection openConnection(final URL u) throws IOException {
    //May instead use VFS DefaultURLConnection
    return new URLConnection(u) {
      @Override
      public void connect() throws IOException {}

      @Override
      public InputStream getInputStream() throws IOException {
        FileSystemManager fsManager = VFS.getManager();
        FileObject entry = fsManager.resolveFile(u.toExternalForm());
        FileContent content = entry.getContent();
        return content.getInputStream();
      }
    };
  }
}

Then there will be no malformed url exception:

UrlSchemeRegistry.register("ram", RamHandler.class);
URL url = new URL("ram:///A/B/sample.jar");

VFS supports creating a stream handler factory which knows about all the registered schemes.

// you might want to configure a manager with less schemes
FileSystemManager fsm = VFS.getManager(); 
URLStreamHandlerFactory factory = fsm.getURLStreamHandlerFactory();
URL.setURLStreamHandlerFactory(factory); // VM global
URL url = new URL("ram://test.txt");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM