java操作hdfs,实现文件上传、下载以及查看当前文件夹下所有文件

本文介绍如何使用Java操作Hadoop分布式文件系统(HDFS),包括文件上传、下载及目录浏览等基本功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。下面我简单说说用Java实现对HDFS文件进行上传、下载以及查看当前文件夹下所有文件:

开始前准备工作:

搭建一个分布式或者伪分布式的Hadoop集群,这个有问题的请看我以前写的文章,传送阵

eclipse,建议使用eclipse4.4以上版本;

第一步:

配置Hadoop主目录:

解压Hadoop-2.6.0文件到D盘根目录下,然后配置eclipse的Hadoop主目录;


第二步:配置插件:

打开Windows->Open Perspective中的Map/Reduce,在此perspective下进行hadoop程序开发。


打开Windows->Show View中的Map/Reduce Locations,如下图右键选择New Hadoop location…新建hadoop连接。



确认完成以后如下,eclipse会连接hadoop集群。


第三步:创建maven项目

new一个项目,选择other,然后找到maven project,单击下一步:


默认,单击next:


默认,单击nest:


按照下图填写内容,完成后单击Finish:


第四步:配置pom.xml文件:


    <dependency>
	    <groupId>org.apache.hadoop</groupId>
	    <artifactId>hadoop-client</artifactId>
	    <version>2.5.0</version>
	</dependency>
第五步:创建一个class文件,命名为MyHdfs,代码如下:

package archy.com;

import java.io.InputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

public class MyHdfs {
	// hadoop fs的配置文件
	static Configuration conf = new Configuration(true);
	static {
		// 指定hadoop fs的地址
		conf.set("fs.default.name", "hdfs://bigdata01.com:8020");
	}

	/**
	 * 将本地文件(filePath)上传到HDFS服务器的指定路径(dst)
	 * 
	 * @author 冯琪
	 */
	public static void uploadFileToHDFS(String filePath, String dst)
			throws Exception {
		// 创建一个文件系统
		FileSystem fs = FileSystem.get(conf);
		Path srcPath = new Path(filePath);
		Path dstPath = new Path(dst);
		Long start = System.currentTimeMillis();
		fs.copyFromLocalFile(false, srcPath, dstPath);
		System.out.println("Time:" + (System.currentTimeMillis() - start));
		System.out.println("________准备上传文件" + conf.get("fs.default.name")
				+ "____________");
		fs.close();
		getDirectoryFromHdfs(dst);
	}

	/**
	 * 下载文件
	 * 
	 * @author 冯琪
	 */
	public static void downLoadFileFromHDFS(String src) throws Exception {
		FileSystem fs = FileSystem.get(conf);
		Path srcPath = new Path(src);
		InputStream in = fs.open(srcPath);
		try {
			// 将文件COPY到标准输出(即控制台输出)
			IOUtils.copyBytes(in, System.out, 4096, false);
		} finally {
			IOUtils.closeStream(in);
			fs.close();
		}
	}

	/**
	 * 遍历指定目录(direPath)下的所有文件
	 * 
	 * @author 冯琪
	 */
	public static void getDirectoryFromHdfs(String direPath) throws Exception {

		FileSystem fs = FileSystem.get(URI.create(direPath), conf);
		FileStatus[] filelist = fs.listStatus(new Path(direPath));
		for (int i = 0; i < filelist.length; i++) {
			System.out.println("_________________第" + i + "个文件"
					+ "____________________");
			FileStatus fileStatus = filelist[i];
			System.out.println("Name:" + fileStatus.getPath().getName());
			System.out.println("size:" + fileStatus.getLen());
			System.out.println("_________________第" + i + "个文件"
					+ "____________________");
		}
		fs.close();
	}

	/**
	 * 测试方法
	 * 
	 * @author 冯琪
	 */
	public static void main(String[] args) {
		try {
			// 获取目录下的所有文件,hdfs服务器文件夹路径
			getDirectoryFromHdfs("/fengqi/1104/");
			// 上传文件,第一个参数为本地要上传的文件路径,第二个参数为HDFS的路径。
			// uploadFileToHDFS("D:/456.txt", "/fengqi/1104/");
			// 下载文件,第一个参数为HDFS上要下载的文件路径
			// downLoadFileFromHDFS("/fengqi/1104/456.txt");
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}



第六步:测试结果






如果有什么疑问或者见解,欢迎在下方留言,谢谢。

### Java API HDFS 文件上传失败的原因分析 当通过 Java API 将本地文件上传HDFS 时,如果文件未显示或上传失败,可能是由以下几种常见原因引起的: #### 1. **HDFS URI 配置错误** 如果 `Configuration` 对象中的 `fs.defaultFS` 属性配置不正确,例如使用了无效的主机名或端口号,则可能导致客户端无法连接到 HDFS 集群。即使防火墙已关闭且端口开放,错误的 URI 配置仍会阻碍连接建立[^4]。 #### 2. **目标路径冲突** 如果目标路径在 HDFS 上已经存在,并且程序逻辑未正确处理覆盖或追加的情况,可能会导致上传失败。默认情况下,`copyFromLocalFile` 方法不允许覆盖已有文件,除非显式设置参数允许覆盖[^3]。 #### 3. **权限不足** 用户账户可能缺乏对目标目录的操作权限。HDFS 的访问控制严格依赖于用户的权限设置,若当前用户无权向目标目录写入数据,则操作会被拒绝[^3]。 #### 4. **DataNode 不可用** 日志中出现类似于 `could only be replicated to 0 nodes instead of minReplication (=1)` 的错误提示表明 DataNode 可能不可用或配置不当。这通常是由于 DataNode 没有启动、磁盘空间不足或网络问题所致[^5]。 #### 5. **临时目录配置问题** Hadoop 的临时目录 (`hadoop.tmp.dir`) 需要有足够的空间供内部操作使用。如果此目录被删除或空间耗尽,也会引发各种异常行为[^4]。 #### 6. **编码兼容性问题** 特殊字符集的文件(如包含非 ASCII 字符)在传输过程中可能发生编码转换错误,进而影响文件的正常解析与存储。 --- ### 解决方法 针对上述每种可能性,以下是对应的解决办法: #### 1. 核实 HDFS URI 确认 `core-site.xml` 中的 `fs.defaultFS` 是否指向正确的 IP 地址而非仅限 localhost。例如: ```xml <property> <name>fs.defaultFS</name> <value>hdfs://<Your_IP>:9000</value> </property> ``` #### 2. 处理路径冲突 在调用 `copyFromLocalFile` 方法时传递布尔值参数以决定是否覆盖现有文件。例如: ```java fs.copyFromLocalFile(true /* overwrite */, false /* use raw local file system */, srcPath, dstPath); ``` #### 3. 调整安全策略 使用命令行工具检查并调整目标目录的 ACL 设置,确保当前用户拥有必要的读写权限: ```bash hdfs dfs -setfacl -R -m user:<username>:rw- /target/directory ``` #### 4. 检查 DataNode 状态 登录到 Hadoop 集群节点上运行以下命令验证 DataNode 的健康状况: ```bash jps ``` 应能看到 `DataNode` 列表项;否则需依据具体环境排查服务启动脚本及相关日志记录。 #### 5. 清理临时目录 查找并清理占用过多空间的临时文件夹内容,释放更多资源给 Hadoop 使用。可通过修改 `core-site.xml` 改变默认位置以便更好地管理这些中间产物。 #### 6. 文本编码规范化 提前将待上传文件转换成通用标准格式(比如 UTF-8),避免因字节序列解释歧义而导致意外丢失部分信息的现象发生。 --- ### 示例代码片段 下面展示了一个完整的示例程序,演示如何利用 Java API 实现带覆盖选项的文件上传功能: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; public class HDFSUploader { public static void main(String[] args) { String uri = "hdfs://<Your_IP>:9000"; Path srcPath = new Path("/path/to/local/file"); Path dstPath = new Path("/path/in/hdfs"); try { Configuration conf = new Configuration(); conf.set("fs.defaultFS", uri); FileSystem fs = FileSystem.get(conf); boolean isOverwrite = true; // Set this flag as needed. fs.copyFromLocalFile(isOverwrite, false, srcPath, dstPath); System.out.println("File uploaded successfully."); } catch (Exception e) { e.printStackTrace(); } } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值