Java Api操作HDFS
使用idea工具
创建的是maven项目,操作linux环境
首先需要配置好Maven环境,如果下载jar包下的慢,可以将镜像站换为阿里云的镜像【配置maven环境参考:...............(待完成)】
准备工作完成即可开始编写代码
1.创建maven项目



2.在pom.xml里面导入依赖
pom.xml中所使用到的jar包【自行去maven仓库找jar包,认准下载量最多的。https://mvnrepository.com/】
如果网站加载的太慢,可以去阿里云的maven仓库找:https://maven.aliyun.com/
hadoop-common,hadoop-hdfs,hadoop-client【3个版本保持一致】
<dependencies>
<!--测试用-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--COMMON是hadoop一切的核心,不是具体的功能,操作HDFS需要导入COMMON的依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<!--hadoop也是基于客户端服务器的-->
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<!--操作MapReduce需要HDFS的依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>3.开始编写代码
3.1.连接HDFS
//连接HDFS
@Test //测试
public void connectHDFS(){
//先添加一个配置文件--和core-site.xml的配置一样[相当于服务器的端口]
Configuration conf = new Configuration();
//配置服务器的地址和端口
conf.set("fs.defaultFS","hdfs://192.168.0.10:9000");
try {
//加载我们的配置文件,然后连接到服务上去【前提,hadoop的环境配好,启动起来】
FileSystem fileSystem = FileSystem.get(conf);
//如何判断是否已经连上?
//getFileStatus是获取当前某个路径的状态
FileStatus status = fileSystem.getFileStatus(new Path("/test.txt"));
System.out.println(status.isFile()); //判断是不是一个文件
System.out.println(status.isDirectory()); //判断是不是一个目录
System.out.println(status.getPath()); //获取文件的路径
System.out.println(status.getLen()); //获取文件的大小
//关闭连接
fileSystem.close();
} catch (IOException e) {
e.printStackTrace();
}
}3.2.文件上传到HDFS【linux命令:hadoop fs -put】
//上传文件到HDFS
@Test //测试
public void upload1(){
//添加配置文件
Configuration conf = new Configuration();
//如果报一个错误:
//user=Machenike, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
//解决1:直接添加System.setProperty("HADOOP_USER_NAME", "root"); 设置为root用户
//解决2:在环境变量中添加 HADOOP_USER_NAME 值为root
System.setProperty("HADOOP_USER_NAME", "root");
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//获取一个输出流
FSDataOutputStream out = fileSystem.create(new Path("/upload.txt"));
//获取本地文件的一个输入流
FileInputStream in = new FileInputStream(new File("F:\\upload.txt"));
//先定义一个byte类型的数组,数组长度1024
//该数组的大小表示每次从文件中读取出来的数据量
byte[] b = new byte[1024];
int len = 0;
//判断文件是否读完
while((len=in.read(b))!=-1){
//对这些数据量进行输出
//b-表示要写的数据,0-表示从0开始,len-表示写的字节数
out.write(b,0,len);
}
//将输入流和输出流关闭
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
//文件上传方式2-直接使用hadoop提供的一个工具类IOUtils
@Test //测试
public void upload2(){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//获取一个输出流
FSDataOutputStream out = fileSystem.create(new Path("/upload1.txt"));
//获取本地文件的一个输入流
FileInputStream in = new FileInputStream(new File("F:\\upload.txt"));
//执行上传操作
IOUtils.copyBytes(in,out,conf);
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}可能会遇到如下错误:如何解决?
解决办法:
1.直接在代码中设置属性->System.setProperty("HADOOP_USER_NAME", "root");
2.在环境变量中添加HADOOP_USER_NAME 值为root即可【如果不行,重启idea,再不行就重启电脑就OK了】

3.3.从HDFS上下载文件到本地【linux命令:hadoop fs -get】
//文件下载
@Test
public void download(){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//获取输入流的数据
FSDataInputStream in = fileSystem.open(new Path("/upload.txt"));
//获取本地文件的输出流
FileOutputStream out = new FileOutputStream(new File("F:\\download.txt"));
//下载的方式同样有两种【下载就是拷贝】
//方式1:工具类操作
// IOUtils.copyBytes(in,out,conf);
//方式2:
byte[] b = new byte[1024];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
//关闭连接
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}3.4.修改HDFS下的文件名
//重命名
@Test //测试
public void rename(){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//重命名
boolean rename = fileSystem.rename(new Path("/upload.txt"), new Path("/upload3.txt"));
System.out.println(rename?"修改成功":"修改失败");
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}3.5.创建文件夹【linux命令:hadoop fs -mkdir -p】
//创建文件夹
@Test //测试
public void mkdirs(){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//创建多级目录
boolean mkdirs = fileSystem.mkdirs(new Path("/test/test1/hello.txt"));
System.out.println(mkdirs?"城建成功":"创建失败");
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}3.6.查看所有文件夹【linux命令:hadoop fs -lsr】
//查看所有文件夹
@Test //测试
public void selectAll(){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//查询该路径下所有的文件信息
FileStatus[] status = fileSystem.listStatus(new Path("/"));
//遍历所有的文件的状态
System.out.println("/");
for (FileStatus f:status){
//判断是否是文件
//f.getPath().getName() 获取文件或文件夹的名字
//f.getPermission() 获取文件或文件夹的权限
//f.getLen() 获取文件或文件夹的大小
if (f.isFile()){
System.out.println("f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
}else{
System.out.println("d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
getNodes(f.getPath().getName(), 1);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
//递归遍历出所有的文件和文件夹【index主要就是为了打印出来的好看些,强迫症】
public void getNodes(String dir, int index){
//添加配置文件
Configuration conf = new Configuration();
try {
//加载配置文件
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf);
//得到之后新目录的绝对路径
String path = "/"+dir;
//使其具有层次感的制表符
String tab = "\t";
if(index > 1){
for(int i = 1; i < index; i++){
tab += "\t";
}
}
//获取该路径下的所有文件信息
FileStatus[] status = fileSystem.listStatus(new Path(path));
//设置让其退出的条件【如果该路径下没有文件或文件夹即退出】
if(status.length==0){
return;
}
//遍历所有的文件信息
for (FileStatus f : status){
if (f.isFile()){
System.out.println(tab+"f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
}else{
System.out.println(tab+"d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen());
getNodes(dir +"/"+f.getPath().getName(), index +1);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}结果如下:

使用Eclipse工具
需要自己导入jar包。jar包如何找?【将hadoop-2.7.7.tar.gz包解压即可】
jar包 -- 操作hdfs,需要导入Common下的jar包
share/hadoop/common/lib下面作者引用别人的jar包
share/hadoop/common下面自己写的jar包
-- 操作MapReduce,还需要导入HDFS下的jar包
share/hadoop/hdfs/lib 下面作者引用别人的jar包
share/hadoop/hdfs 下面作者自己写的包
代码部分和idea一样的操作