大数据-使用Java API操作HDFS

一、编写Java程序访问HDFS

1、创建Maven项目

创建Maven项目 - HDFSDemo
大数据-使用Java API操作HDFS_第1张图片

2、添加相关依赖

在pom.xml文件里添加hadoop和junit依赖大数据-使用Java API操作HDFS_第2张图片

<dependencies>             
    <!--hadoop客户端-->                       
    <dependency>                                  
        <groupId>org.apache.hadoop</groupId>      
        <artifactId>hadoop-client</artifactId>    
        <version>3.3.4</version>                  
    </dependency>     
    <!--单元测试框架-->                            
    <dependency>                                  
        <groupId>junit</groupId>                  
        <artifactId>junit</artifactId>            
        <version>4.13.2</version>                 
    </dependency>                                 
</dependencies>                                                      

3、创建日志属性文件

在resources目录里创建log4j.properties文件
大数据-使用Java API操作HDFS_第3张图片

log4j.rootLogger=stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/hdfs.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

4、启动集群HDFS服务

在主节点上执行命令:start-dfs.sh
大数据-使用Java API操作HDFS_第4张图片

在Hadoop WebUI界面查看
大数据-使用Java API操作HDFS_第5张图片

5、在HDFS上创建文件

在HDFS Shell里利用hdfs dfs -touchz命令可以创建时间戳文件

任务:在/ied01目录创建hadoop.txt文件

创建net.hf.hdfs包,在包里创建CreateFileOnHDFS类
大数据-使用Java API操作HDFS_第6张图片

编写create1()方法
大数据-使用Java API操作HDFS_第7张图片

package net.hf.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

import java.net.URI;

/**
 * 功能:在HDFS上创建文件
 * 作者:hf
 * 日期:2022年11月25日
 */
public class CreateFileOnHDFS {
    @Test
    public void create1() throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        // 定义统一资源标识符(uri: uniform resource identifier)
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)
        FileSystem fs = FileSystem.get(new URI(uri), conf);
        // 创建路径对象(指向文件)
        Path path = new Path(uri + "/ied01/hadoop.txt");
        // 基于路径对象创建文件
        boolean result = fs.createNewFile(path);
        // 根据返回值判断文件是否创建成功
        if (result) {
            System.out.println("文件[" + path + "]创建成功!");
        } else {
            System.out.println("文件[" + path + "]创建失败!");
        }
    }
}

运行程序,查看结果
大数据-使用Java API操作HDFS_第8张图片

利用Hadoop WebUI查看
大数据-使用Java API操作HDFS_第9张图片

编写create2()方法,事先判断文件是否存在
大数据-使用Java API操作HDFS_第10张图片

 @Test
    public void create2() throws Exception {
        // 创建配置对象                                                            
        Configuration conf = new Configuration();
        // 定义统一资源标识符(uri:uniform resource identifier)                        
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)                                             
        FileSystem fs = FileSystem.get(new URI(uri), conf);
        // 创建路径对象                                                            
        Path path = new Path(uri + "/ied01/hadoop.txt");
        // 判断路径对象指向的文件是否存在                                                   
        if (fs.exists(path)) {
            // 提示用户文件已存在                                                     
            System.out.println("文件[" + path + "]已经存在!");
        } else {
            // 基于路径对象创建文件                                                    
            boolean result = fs.createNewFile(path);
            // 根据返回值判断文件是否创建成功                                               
            if (result) {
                System.out.println("文件[" + path + "]创建成功!");
            } else {
                System.out.println("文件[" + path + "]创建失败!");
            }
        }
    }

运行程序,查看结果
大数据-使用Java API操作HDFS_第11张图片

6、写入HDFS文件

类似于HDFS Shell里的hdfs dfs -put命令
在net.hf.hdfs包里创建WriteFileOnHDFS类
大数据-使用Java API操作HDFS_第12张图片

(1)将数据直接写入HDFS文件
任务:在/ied01目录里创建hello.txt文件

创建write1()方法
大数据-使用Java API操作HDFS_第13张图片
运行write1()测试方法,查看结果,抛出RemoteException异常,三个数据节点都在运行,但是无法写入数据
大数据-使用Java API操作HDFS_第14张图片
修改代码,设置数据节点主机名属性,如下图所示
大数据-使用Java API操作HDFS_第15张图片

package net.hf.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.net.URI;

/**
 * 功能:写入HDFS文件
 * 作者:hf
 * 日期:2022年11月30日
 */
public class WriteFileOnHDFS {
    @Test
    public void write1() throws Exception {
        //创建配置对象
        Configuration conf = new Configuration();
        // 设置数据节点主机名属性
        conf.set("dfs.client.use.datanode.hostname", "true");
        // 定义uri字符串
        String uri = "hdfs://master:9000";
        // 创建文件系统对象
        FileSystem fs = FileSystem.get(new URI(uri), conf, "root");
        // 创建路径对象(指向目录或文件)
        Path path = new Path(uri + "/ied01/hello.txt");
        // 创建文件系统数据字节输出流
        FSDataOutputStream out = fs.create(path);
        // 通过字节输出流向文件写数据
        out.write("Hello Hadoop World".getBytes());
        // 关闭输出流
        out.close();
        // 关闭文件系统对象
        fs.close();
        // 提示用户写入文件成功
        System.out.println("文件[" + path + "]写入成功!");
    }
}

运行程序,查看结果
大数据-使用Java API操作HDFS_第16张图片

利用Hadoop WebUI查看hello.txt文件
大数据-使用Java API操作HDFS_第17张图片

(2)将本地文件写入HDFS文件

在项目根目录创建一个文本文件test.txt
大数据-使用Java API操作HDFS_第18张图片

创建write2()方法
大数据-使用Java API操作HDFS_第19张图片

@Test
    public void write2() throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        // 设置数据节点主机名属性
        conf.set("dfs.client.use.datanode.hostname", "true");
        // 定义统一资源标识符(uri: uniform resource identifier)
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)
        FileSystem fs = FileSystem.get(new URI(uri), conf, "root");
        // 创建路径对象(指向文件)
        Path path = new Path(uri + "/ied01/exam.txt");
        // 创建文件系统数据字节输出流(出水管:数据从程序到文件)
        FSDataOutputStream out = fs.create(path);
        // 创建文件字符输入流对象(进水管:数据从文件到程序)
        FileReader fr = new FileReader("test.txt");
        // 创建缓冲字符输入流对象
        BufferedReader br = new BufferedReader(fr);
        // 定义行字符串变量
        String nextLine = "";
        // 通过循环遍历缓冲字符输入流
        while ((nextLine = br.readLine()) != null) {
            // 在控制台输出读取的行
            System.out.println(nextLine);
            // 通过文件系统数据字节输出流对象写入指定文件
            out.write((nextLine + "\n").getBytes());
        }
        // 关闭缓冲字符输入流
        br.close();
        // 关闭文件字符输入流
        fr.close();
        // 关闭文件系统数据字节输出流
        out.close();
        // 提示用户写入文件成功
        System.out.println("本地文件[test.txt]成功写入[" + path + "]!");
    }

运行write2()测试方法,查看结果大数据-使用Java API操作HDFS_第20张图片

查看/ied01/exam.txt内容
大数据-使用Java API操作HDFS_第21张图片

通过使用一个工具类IOUtils来更简单的处理
编写write2_()方法大数据-使用Java API操作HDFS_第22张图片
运行write2_()测试方法,查看结果大数据-使用Java API操作HDFS_第23张图片
查看/ied01/test.txt内容,文件是存在的,但是没有内容在这里插入图片描述

再次读取文件,让字节输入流有数据大数据-使用Java API操作HDFS_第24张图片

@Test
    public void write2_() throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        // 设置数据节点主机名属性
        conf.set("dfs.client.use.datanode.hostname", "true");
        // 定义统一资源标识符(uri: uniform resource identifier)
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)
        FileSystem fs = FileSystem.get(new URI(uri), conf, "root");
        // 创建路径对象(指向文件)
        Path path = new Path(uri + "/ied01/test.txt");
        // 创建文件系统数据字节输出流(出水管:数据从程序到文件)
        FSDataOutputStream out = fs.create(path);
        // 创建文件字节输入流(进水管:数据从文件到程序)
        FileInputStream in = new FileInputStream("test.txt");
        // 利用IOUtils类提供的字节拷贝方法在控制台显示文件内容
        IOUtils.copyBytes(in, System.out, 1024, false);
        // 再次读取文件数据到文件字节输入流
        in = new FileInputStream("test.txt");
        // 利用IOUtils类提供的字节拷贝方法来复制文件
        IOUtils.copyBytes(in, out, conf);
        // 关闭文件字节输入流
        in.close();
        // 关闭文件系统数据字节输出流
        out.close();
        // 提示用户写入文件成功
        System.out.println("本地文件[test.txt]成功写入[" + path + "]!");
    }

运行write2_()方法,查看结果大数据-使用Java API操作HDFS_第25张图片
查看/ied01/test.txt文件
在这里插入图片描述

7、读取HDFS文件

相当于Shell里的两个命令:hdfs dfs -cat和hdfs dfs -get
在net.hf.hdfs包里创建ReadFileOnHDFS类
大数据-使用Java API操作HDFS_第26张图片

(1)读取HDFS文件直接在控制台显示

准备读取hdfs://master:9000/ied01/test.txt文件
大数据-使用Java API操作HDFS_第27张图片
编写read1()方法
大数据-使用Java API操作HDFS_第28张图片

运行read1()测试方法,查看结果
大数据-使用Java API操作HDFS_第29张图片
可以使用IOUtils类来简化代码,创建read1_()测试方法大数据-使用Java API操作HDFS_第30张图片
运行read1_()测试方法,查看结果
大数据-使用Java API操作HDFS_第31张图片

(2)读取HDFS文件,保存为本地文件
任务:将/ied01/test.txt下载到项目的download目录里

创建download目录
大数据-使用Java API操作HDFS_第32张图片
创建read2()方法
大数据-使用Java API操作HDFS_第33张图片

@Test
    public void read2() throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        // 设置数据节点主机名属性
        conf.set("dfs.client.use.datanode.hostname", "true");
        // 定义统一资源标识符(uri: uniform resource identifier)
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)
        FileSystem fs = FileSystem.get(new URI(uri), conf, "root");
        // 创建路径对象(指向文件)
        Path path = new Path(uri + "/ied01/test.txt");
        // 创建文件系统数据字节输入流(进水管:数据从文件到程序)
        FSDataInputStream in = fs.open(path);
        // 创建文件字节输出流(出水管:数据从程序到文件)
        FileOutputStream out = new FileOutputStream("download/exam.txt");
        // 利用IOUtils工具类读取HDFS文件(靠输入流),写入本地文件(靠输出流)
        IOUtils.copyBytes(in, out, conf);
        // 关闭文件字节输出流
        out.close();
        // 关闭文件系统数据字节流输入流
        in.close();
        // 关闭文件系统
        fs.close();
        // 提示用户文件下载成功
        System.out.println("文件[" + path + "]下载到本地文件[download/exam.txt]!");
    }

运行read2()测试方法,查看结果大数据-使用Java API操作HDFS_第34张图片

8、重命名目录或文件

相当于Shell里的hdfs dfs -mv命令
在net.hf.hdfs包里创建RenameDirOrFile类
大数据-使用Java API操作HDFS_第35张图片

(1)重命名目录
任务:将/ied01目录更名为/lzy01

编写renameDir()方法
大数据-使用Java API操作HDFS_第36张图片
运行renameDir()方法,查看结果
大数据-使用Java API操作HDFS_第37张图片
利用Hadoop WebUI界面查看
大数据-使用Java API操作HDFS_第38张图片

(2)重命名文件
任务:将lzy01目录下的hello.txt重命名为hi.txt大数据-使用Java API操作HDFS_第39张图片

编写renameFile()方法
大数据-使用Java API操作HDFS_第40张图片

@Test
    public void renameFile() throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        // 设置数据节点主机名属性
        conf.set("dfs.client.use.datanode.hostname", "true");
        // 定义统一资源标识符(uri: uniform resource identifier)
        String uri = "hdfs://master:9000";
        // 创建文件系统对象(基于HDFS的文件系统)
        FileSystem fs = FileSystem.get(new URI(uri), conf, "root");
        // 创建源路径对象(指向文件)
        Path sourcePath = new Path(uri + "/lzy01/hello.txt");
        // 创建目标路径对象(指向文件)
        Path destinationPath = new Path(uri + "/lzy01/hi.txt");
        // 利用文件系统对象重命名文件
        fs.rename(sourcePath, destinationPath);
        // 关闭文件系统
        fs.close();
        // 提示用户文件更名成功
        System.out.println("文件[" + sourcePath.getName() + "]更名为文件[" + destinationPath.getName() + "]!");
    }

运行renameFile()测试方法,查看结果
大数据-使用Java API操作HDFS_第41张图片
利用Hadoop WebUI界面查看
大数据-使用Java API操作HDFS_第42张图片

9、显示文件列表

在net.hf.hdfs包里创建ListHDFSFiles类
大数据-使用Java API操作HDFS_第43张图片

(1)显示指定目录下文件全部信息
任务:显示/lzy01目录下的文件列表

大数据-使用Java API操作HDFS_第44张图片
编写list1()方法
大数据-使用Java API操作HDFS_第45张图片
运行list1()测试方法,查看结果
大数据-使用Java API操作HDFS_第46张图片
上述文件状态对象封装的有关信息,可以通过相应的方法来获取,比如getPath()方法就可以获取路径信息,getLen()方法就可以获取文件长度信息……

(2)显示指定目录下文件路径和长度信息

编写list2()方法
大数据-使用Java API操作HDFS_第47张图片
运行list2()测试方法,查看结果
大数据-使用Java API操作HDFS_第48张图片
对照Hadoop WebUI上给出的文件长度信息
大数据-使用Java API操作HDFS_第49张图片

10、获取文件块信息

任务:获取/lzy01/hadoop-3.3.4.tar.gz文件块信息大数据-使用Java API操作HDFS_第50张图片

hadoop压缩包会分割成6个文件块
大数据-使用Java API操作HDFS_第51张图片
在net.hf.hdfs包里创建GetBlockLocations类
大数据-使用Java API操作HDFS_第52张图片
编写代码,获取文件块信息
大数据-使用Java API操作HDFS_第53张图片
运行程序,查看结果(切点位置,块大小,块存在位置)大数据-使用Java API操作HDFS_第54张图片

11、创建目录

任务:在HDFS上创建/ied01目录

在net.hf.hdfs包里创建MakeDirOnHDFS类
大数据-使用Java API操作HDFS_第55张图片
大数据-使用Java API操作HDFS_第56张图片
运行程序,查看结果
大数据-使用Java API操作HDFS_第57张图片
利用Hadoop WebUI界面查看
大数据-使用Java API操作HDFS_第58张图片

12、判断目录或文件是否存在

任务:判断HDFS上/ied01目录是否存在,判断/ied01/hadoop.txt文件是否存在

在net.hf.hdfs包里创建DirFileExistsOrNot类
大数据-使用Java API操作HDFS_第59张图片
编写dirExists()方法
大数据-使用Java API操作HDFS_第60张图片
运行程序,查看结果
大数据-使用Java API操作HDFS_第61张图片
修改代码,再测试
大数据-使用Java API操作HDFS_第62张图片
编写fileExists()方法大数据-使用Java API操作HDFS_第63张图片
运行程序,查看结果
大数据-使用Java API操作HDFS_第64张图片

13、判断Path指向目录还是文件

在net.hf.hdfs包里创建PathToFileOrDir类大数据-使用Java API操作HDFS_第65张图片
大数据-使用Java API操作HDFS_第66张图片
运行程序,查看结果
大数据-使用Java API操作HDFS_第67张图片

14、删除目录或文件

类似于HDFS Shell里的hdfs dfs -rmdir和hdfs dfs -rm -r命令
在net.hf.hdfs包里创建DeleteFileOrDir类
大数据-使用Java API操作HDFS_第68张图片

(1)删除文件
任务:删除/lzy01/hi.txt文件

大数据-使用Java API操作HDFS_第69张图片
编写deleteFile()方法
大数据-使用Java API操作HDFS_第70张图片
运行deleteFile()测试方法,查看结果
大数据-使用Java API操作HDFS_第71张图片
利用Hadoop WebUI界面查看
大数据-使用Java API操作HDFS_第72张图片
再运行deleteFile()测试方法,查看结果
大数据-使用Java API操作HDFS_第73张图片
可以在删除文件之前,判断文件是否存在,需要修改代码大数据-使用Java API操作HDFS_第74张图片
此时运行deleteFile()测试方法,查看结果
大数据-使用Java API操作HDFS_第75张图片

(2)删除目录
任务:删除/lzy01目录

编写deleteDir()方法
大数据-使用Java API操作HDFS_第76张图片
运行deleteDir()方法,查看结果
大数据-使用Java API操作HDFS_第77张图片
再运行deleteDir()方法,查看结果
大数据-使用Java API操作HDFS_第78张图片

(3)删除目录或文件

进行三个层面的判断:判断是否存在、判断类型(目录或文件)、判断删除是否成功

任务:删除/ied02/exam.txt文件和/lzy01目录大数据-使用Java API操作HDFS_第79张图片

大数据-使用Java API操作HDFS_第80张图片
运行程序,查看结果
大数据-使用Java API操作HDFS_第81张图片
再次运行程序,查看结果
大数据-使用Java API操作HDFS_第82张图片

你可能感兴趣的:(hdfs,大数据,java)