Java操作hdfs,总是报ClosedChannelException

2024-04-03 21:20

本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/874010

相关文章

JAVA虚拟机中 -D, -X, -XX ,-server参数使用

《JAVA虚拟机中-D,-X,-XX,-server参数使用》本文主要介绍了JAVA虚拟机中-D,-X,-XX,-server参数使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录一、-D参数二、-X参数三、-XX参数总结:在Java开发过程中,对Java虚拟机(JVM)的启动参数进

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

Java中使用注解校验手机号格式的详细指南

《Java中使用注解校验手机号格式的详细指南》在现代的Web应用开发中,数据校验是一个非常重要的环节,本文将详细介绍如何在Java中使用注解对手机号格式进行校验,感兴趣的小伙伴可以了解下... 目录1. 引言2. 数据校验的重要性3. Java中的数据校验框架4. 使用注解校验手机号格式4.1 @NotBl

SpringBoot自定义注解如何解决公共字段填充问题

《SpringBoot自定义注解如何解决公共字段填充问题》本文介绍了在系统开发中,如何使用AOP切面编程实现公共字段自动填充的功能,从而简化代码,通过自定义注解和切面类,可以统一处理创建时间和修改时间... 目录1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3

SpringBoot基于沙箱环境实现支付宝支付教程

《SpringBoot基于沙箱环境实现支付宝支付教程》本文介绍了如何使用支付宝沙箱环境进行开发测试,包括沙箱环境的介绍、准备步骤、在SpringBoot项目中结合支付宝沙箱进行支付接口的实现与测试... 目录一、支付宝沙箱环境介绍二、沙箱环境准备2.1 注册入驻支付宝开放平台2.2 配置沙箱环境2.3 沙箱

使用Java发送邮件到QQ邮箱的完整指南

《使用Java发送邮件到QQ邮箱的完整指南》在现代软件开发中,邮件发送功能是一个常见的需求,无论是用户注册验证、密码重置,还是系统通知,邮件都是一种重要的通信方式,本文将详细介绍如何使用Java编写程... 目录引言1. 准备工作1.1 获取QQ邮箱的SMTP授权码1.2 添加JavaMail依赖2. 实现

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

C#中的 Dictionary常用操作

《C#中的Dictionary常用操作》C#中的DictionaryTKey,TValue是用于存储键值对集合的泛型类,允许通过键快速检索值,并且具有唯一键、动态大小和无序集合的特性,常用操作包括添... 目录基本概念Dictionary的基本结构Dictionary的主要特性Dictionary的常用操作

java两个List的交集,并集方式

《java两个List的交集,并集方式》文章主要介绍了Java中两个List的交集和并集的处理方法,推荐使用Apache的CollectionUtils工具类,因为它简单且不会改变原有集合,同时,文章... 目录Java两个List的交集,并集方法一方法二方法三总结java两个List的交集,并集方法一

Spring AI集成DeepSeek三步搞定Java智能应用的详细过程

《SpringAI集成DeepSeek三步搞定Java智能应用的详细过程》本文介绍了如何使用SpringAI集成DeepSeek,一个国内顶尖的多模态大模型,SpringAI提供了一套统一的接口,简... 目录DeepSeek 介绍Spring AI 是什么?Spring AI 的主要功能包括1、环境准备2