hdfs java.io.IOException: Mkdirs failed to create

在阅读《Hadoop in Action》第三章时,遇到使用HDFS Java API合并文件时的异常。错误源于试图创建的FileSystem实例为本地文件系统而非HDFS。通过打印确认获取的FileSystem是file:///。问题出在`FileSystem.get(conf)`,它默认返回本地文件系统。解决方案是使用`FileSystem.get(URI.create("hdfs://localhost:9000/"), conf)`明确指定HDFS地址。调整后程序运行正常。" 130498181,14095129,CSS3动画详解与实现,"['前端', 'CSS', 'HTML', 'CSS3']

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

学习到 <<Hadoop in Action>> chapter 3.1时,使用hdfs java api编写FileMerge时发现报个错误,开始时觉得有点莫名其妙,后来查看api才只有原来是这样。


需求: 准备把local file system 中的某个文件夹下所有文件,合并到hdfs文件系统中一个文件里。

程序如下:


package com.test.study;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class FileMerge {

	public static void main(String[] args) {
		Path inputDir = new Path(args[0]);
		Path outputFile = new Path(args[1]);
		
		try {
			mergeFile(inputDir, outputFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void mergeFile(Path inputDir, Path outputFile) throws IOException{
		Configuration conf = new Configuration();
		FileSystem local = FileSystem.getLocal(conf);
		FileSystem hdfs = FileSystem.get(conf);
		
		// open output file stream
		FSDataOutputStream out = null;
		if(!hdfs.exists(outputFile)){
			out = hdfs.create(outputFile);
		}else{
			System.out.println("output file ["+outputFile.getName()+"] has existed.");
			return;
		}
		
		FileStatus[] inputFiles = local.listStatus(inputDir);
		FSDataInputStream input = null;
		byte[] buffer = new byte[1024];
		int length = -1;
		for(FileStatus fileStatus: inputFiles){
			if(fileStatus.isDir()){
				continue;
			}
			input = local.open(fileStatus.getPath());
			while((length = input.read(buffer))>0){
				out.write(buffer, 0, length);
			}
			input.close();
		}
		
		out.close();
	}

}

运行程序:  java org.test.study.FileMerge /home/walkerJong/hadoop-1.2/logs /user/walkerJong/hadoop.log


发现报以下错误:

java.io.IOException: Mkdirs failed to create /user/walkerJong
	at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:378)
	at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:364)
	at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:564)
	at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:545)
	at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:452)
	at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:444)
	at com.b5m.study.FileMerge.mergeFile(FileMerge.java:33)
	at com.b5m.study.FileMerge.main(FileMerge.java:19)

百思不得解决,看了看源码,发现还是没找到错在哪里?

最后在 FileSystem hdfs = FileSystem.get(conf);  之后加了一句: System.out.println(hdfs.getName());   打印出来的结果居然是 file:///  

明显获得的FileSystem是 local file system.

错就应该错在 FileSystem hdfs = FileSystem.get(conf); 这里,因为我们想获取得到的时hdfs的文件系统,但是运行结果确实local file system.


查看FileSystem.get()相关api说明发现:

FileSystem.get(Configuration conf) 使用配置文件来获取文件系统, 配置文件conf/core-site.xml,若没有指定则返回local file system. (原来是这样)

FileSystem.get(URI uri, Configuration conf) 根据uri和conf来确定文件系统。


修改程序: FileSystem hdfs = FileSystem.get(URI.create("hdfs://localhost:9000/"), conf); 

再次运行程序,OK;


参考文献:  《Hadoop, The definitive guide, 3rd 》 p57;

Java中,我们可以使用Hadoop的API来读取本地文本文件(如.txt),并将数据加载到HDFS(Hadoop Distributed File System)。以下是使用Apache Hadoop API的一个简单示例: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class LocalToHDFS { public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); // 本地文件路径 Path localFilePath = new Path("file:///path/to/your/local/text.txt"); // HDFS目标路径 Path hdfsTargetPath = new Path("/path/in/hdfs/where/to/save.txt"); // 创建目录(如果不存在) boolean createDir = fs.mkdirs(hdfsTargetPath.getParent()); if (!createDir) { System.err.println("Failed to create directory in HDFS"); return; } try (BufferedReader br = new BufferedReader(new FileReader(localFilePath))) { String line; while ((line = br.readLine()) != null) { // 这里可以对每一行做处理,比如编码转换等,然后写入HDFS fs.append(hdfsTargetPath, () -> new DataOutputStream(fs.create(hdfsTargetPath)), line.getBytes("UTF-8")); } } System.out.println("Data from local file has been copied to HDFS at " + hdfsTargetPath); } } ``` 在这个示例中,我们首先创建一个`Configuration`对象,这是与HDFS交互的基础。然后,我们通过`FileSystem.get()`方法获取到`FileSystem`实例。接着,我们读取本地文件的内容,并将每一行写入HDFS。 注意,你需要在集群上安装Hadoop,并配置好环境才能运行这段代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值