JAVA URL協議擴展支持HDFS

問題:

  • 最近在作天然語言處理的時候,使用了謝菲爾德大學的Gate,奈何Gate只能從本地文件讀取配置和語義文件,特將此改形成從HDFS讀取,而且和Spark集成起來,作到實時解析
  • 改造完成後才發現能夠使用自定義URL來實現,這樣改動量就會少一點,後知後覺,特作此記錄

擴展的兩種方式:

重寫URLStreamHandler

//構造方法
public URL(URL context, String spec, URLStreamHandler handler) throws MalformedURLException

//重寫URLStreamHandler
new URLStreamHandler(){
     @Override
     protected URLConnection openConnection(URL u) throws IOException {
          return null;
     }
 }

//重寫URLConnection, getInputStream,getOutputStream和其餘方法根據可根據實際狀況決定是否重寫
class TestURLConnection extends URLConnection {
    public TestURLConnection(URL url) {
        super(url);
    }

    @Override
    public void connect() throws IOException {
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return super.getInputStream();
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        return super.getOutputStream();
    }
}

重寫URLStreamHandlerFactory

new URLStreamHandlerFactory(){
        @Override
        public URLStreamHandler createURLStreamHandler(String protocol) {
            return null;
        }
}

public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
        synchronized (streamHandlerLock) {
            if (factory != null) {
                throw new Error("factory already defined");
            }
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkSetFactory();
            }
            handlers.clear();
            factory = fac;
        }
    }

本質仍是使用了URLStreamHandler,可是要注意,setURLStreamHandlerFactory只可以調用一次,當工程很大,依賴不少的時候,可能會有框架中的代碼先於業務代碼,調用過此方法,因此爲了不此種狀況,最好使用方法一apache

PS:編寫HDFS的大牛早就想到了,因此直接使用org.apache.hadoop.fs.FsUrlStreamHandler 便可框架

相關文章
相關標籤/搜索