本文主要是介绍Java操作hdfs,总是报ClosedChannelException,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
现象
public boolean uploadFile(MultipartFile file, String dst) {try {long start = System.currentTimeMillis();// 创建Hadoop配置对象Configuration config = new Configuration();config.set("fs.defaultFS", hdfsUri);Path dstPath = new Path(ROOT_PATH + dst);FileSystem fs = dstPath.getFileSystem(config);// 上传文件到HDFSInputStream in = new BufferedInputStream(file.getInputStream());OutputStream out = fs.create(dstPath);IOUtils.copyBytes(in, out, 128000000, true);in.close();// 关闭FileSystem对象fs.close();long end = System.currentTimeMillis();logger.info("文件名称: {} 耗时: {}", dst, end - start);return true;} catch (Exception e) {logger.error("文件:{}, 上传错误!, ", dst, e);return false;}
}
以上代码,如果多个请求同时过来,
会报 java.nio.channels.ClosedChannelException: null at org.apache.hadoop.hdfs.ExceptionLastSeen.throwException4Close
网上居然很难找到正确答案,经过多次尝试,修改后,
public boolean uploadFile(MultipartFile file, String dst) {try {long start = System.currentTimeMillis();// 创建Hadoop配置对象Configuration config = new Configuration();config.set("fs.defaultFS", hdfsUri);Path dstPath = new Path(ROOT_PATH + dst);FileSystem fs = dstPath.getFileSystem(config);// 上传文件到HDFSInputStream in = new BufferedInputStream(file.getInputStream());OutputStream out = fs.create(dstPath);IOUtils.copyBytes(in, out, 4096, true);in.close();// 关闭FileSystem对象<font color="red">// fs.close();</font>long end = System.currentTimeMillis();logger.info("文件名称: {} 耗时: {}", dst, end - start);return true;} catch (Exception e) {logger.error("文件:{}, 上传错误!, ", dst, e);return false;}
}
如上,不要执行fs.close();就好了。
原因:
经过查阅资料和查看源码,
FileSystem fs = dstPath.getFileSystem(config); 不是新建,而是从CACHE中拿。
所以多个请求关了同一个fs。
参考:
https://arganzheng.life/hadoop-filesystem-closed-exception.html
这篇关于Java操作hdfs,总是报ClosedChannelException的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!