hadoop hdfs文件系统对象FileSystem get和newInstance区别

hadoop | 2019-09-13 10:02:39

java操作hdfs文件和操作系统文件方式差不多,但操作hdfs首先要根据集群地址获取FileSystem,然后再进行文件操作。

FileSystem = FileSystem.get(URI.create(hdfsURI), new Configuration());

或者

FileSystem = FileSystem.newInstance(URI.create(hdfsURI), new Configuration());


我之前喜欢用get,我也没探究为什么,而且每次用完我都调用close

但是多线程下报错异常

java.io.IOException: Failed on local exception: java.nio.channels.ClosedByInterruptException; Host Details : local host is: "localhost.localdomain/127.0.0.1"; destination host is: "hadoopMaster":9000; 
at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:776)
...
Caused by: java.nio.channels.ClosedByInterruptException


所以不得不搞清FileSystem get和newInstance区别

查看get得源码:

public static FileSystem get(URI uri, Configuration conf) throws IOException {
    String scheme = uri.getScheme();
    String authority = uri.getAuthority();
    if (scheme == null && authority == null) {// use default FS
      //根据fs.defaultFS的值获取文件系统,若未设置该参数则根据file:///返回文件系统
      return get(conf);
    }
    if (scheme != null && authority == null) {// no authority
      //根据fs.defaultFS的值创建URI,若未设置则使用file:///创建URI
      URI defaultUri = getDefaultUri(conf);
      if (scheme.equals(defaultUri.getScheme())    // if scheme matches default
          && defaultUri.getAuthority() != null) {  // & default has authority
        return get(defaultUri, conf);              // return default
      }
    }
    String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
    if (conf.getBoolean(disableCacheName, false)) {
      //根据uri和conf创建FileSystem
      return createFileSystem(uri, conf);
}
//若未设置缓存参数为true,则默认从CACHE中获取文件系统对象
    return CACHE.get(uri, conf);
}

总结:

从上面的代码可以得知,get方法不是每次都创建FileSystem对象,会从缓存中获取FileSystem对象,而newInstance方法则会每次都创建新对象。所以在使用该对象的API编程时,推荐使用get方法。


注意:用get不能close,否则多线程报错(所以我用static),而用newInstance必须每次close.

登录后即可回复 登录 | 注册
    
关注编程学问公众号