【自编写API】编写HDFS的Java API

HDFS的客户端API

客户端环境准备
  1. 前期准备

    • 确保Windows目录下有JDK,建议用1.8.0版本

    • 下载IDEA

    • 下载maven,根据自己下载的IDEA版本,下载对应的maven版本

    • 配置maven(先配置环境变量,后配置maven中内容)

      1. MAVEN_HOME

        image-20221109102500335

        MAVEN_HOME(低版本中使用MAVEN_HOME,高版本中推荐使用M2_HOME)

      2. Path

        image-20221109102631097

      3. 测试一下maven是否正常启动

        mvn -v
        或者
        mvn -version
        

        image-20221109102923758

      4. 配置Maven本地仓库--conf/settings.xml

            <localRepository>本地仓库目录</localRepository>
        

        image-20221109103155432

        本地仓库目录需提前创建,并保证目录中不含中文字符和空格,以Repository命名

      5. 配置Maven中央仓库为国内的阿里云

            <mirror>
                <id>nexus-aliyun</id>
                <mirrorOf>central</mirrorOf>
                <name>Nexus aliyun</name>
                <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            </mirror>
        

        image-20221109103353728

      6. 配置Maven全局JDK版本,以1.8.0为例

        	<profile>
        		<id>jdk-1.8</id>
        		<activation>
        			<activeByDefault>true</activeByDefault>
        			<jdk>1.8</jdk>
        		</activation>
        		<properties>
        			<maven.compiler.source>1.8</maven.compiler.source>
        			<maven.compiler.target>1.8</maven.compiler.target>
        			<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
        		</properties>
        	</profile>
        

        image-20221109105215293

    • 在IDEA中配置maven项目

      1. 看自己IDEA中是否带Maven插件(专业一般自带,没有需自行安装)

      2. 修改IDEA默认的maven路径

        image-20221109103607059

        勾选Override后修改到自己的settings.xml文件,并配置自己的本地仓库路径

      3. 设置Maven自动导包

        image-20221109103748090

      4. 优化Maven的Runner参数

        -DarchetypeCatalog=internal
        

        image-20221109103800524

  2. 准备下载安装包

    下载Hadoop基于Windows环境的依赖,保存的目录必须为非中文目录且无空格

    百度网盘,提取码为hfmq

    winutils-master.zip中下载对应版本的依赖

    hadooponwindows-master.zip可直接下载使用

  3. 配置变量

    • 配置HADOOP_HOME环境变量

      image-20220713094556821

    • 配置Path环境变量

      image-20220713094624202

  4. 验证Hadoop环境变量是否正常

    image-20220713094744176

  5. 在IDEA中创建一个Maven工程HdfsClientDemo,并导入相应的依赖坐标+日志添加

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
        </dependency>
    </dependencies>
    

    在项目的src/main/resources目录下,新建一个文件,命名为log4j.properties,在文件中填入

    log4j.rootLogger=INFO, stdout  
    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/spring.log  
    log4j.appender.logfile.layout=org.apache.log4j.PatternLayout  
    log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
    
  6. 创建包名:com.hdfs

  7. 创建HdfsClient

    public class HdfsClient {
    
        @Test
        public void testMkdirs() throws IOException, URISyntaxException, InterruptedException {
    
            // 1 获取文件系统
            Configuration configuration = new Configuration();
    
            // FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration);
            FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration,"user");
    
            // 2 创建目录
            fs.mkdirs(new Path("newDir"));
    
            // 3 关闭资源
            fs.close();
        }
    }
    
  8. 执行程序

API实例
  • 文件上传

    @Test
    public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
    
        // 1 获取文件系统
        Configuration configuration = new Configuration();
        configuration.set("dfs.replication", "2");
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
    
        // 2 上传文件
        fs.copyFromLocalFile(new Path("d:/sunwukong.txt"), new Path("/xiyou/huaguoshan"));
    
        // 3 关闭资源
        fs.close();
    }
    

    hdfs-site.xml拷贝到项目的resources资源目录下

    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    
    <configuration>
    	<property>
    		<name>dfs.replication</name>
             <value>1</value>
    	</property>
    </configuration>
    

    参数优先级排序:

    客户端代码中设置的值 > ClassPath下的用户自定义配置文件 > 服务器的自定义配置(xxx-site.xml)> 服务器的默认配置(xxx-default.xml)

  • 文件下载

    @Test
    public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{
    
        // 1 获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
        
        // 2 执行下载操作
        // boolean delSrc 指是否将原文件删除
        // Path src 指要下载的文件路径
        // Path dst 指将文件下载到的路径
        // boolean useRawLocalFileSystem 是否开启文件校验
        fs.copyToLocalFile(false, new Path("/xiyou/huaguoshan/sunwukong.txt"), new Path("d:/sunwukong2.txt"), true);
        
        // 3 关闭资源
        fs.close();
    }
    
  • 文件更名和移动

    @Test
    public void testRename() throws IOException, InterruptedException, URISyntaxException{
    
    	// 1 获取文件系统
    	Configuration configuration = new Configuration();
    	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu"); 
    		
    	// 2 修改文件名称
    	fs.rename(new Path("/xiyou/huaguoshan/sunwukong.txt"), new Path("/xiyou/huaguoshan/meihouwang.txt"));
    		
    	// 3 关闭资源
    	fs.close();
    }
    
  • 删除文件或目录

    @Test
    public void testDelete() throws IOException, InterruptedException, URISyntaxException{
    
    	// 1 获取文件系统
    	Configuration configuration = new Configuration();
    	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
    		
    	// 2 执行删除
    	fs.delete(new Path("/xiyou"), true);
    		
    	// 3 关闭资源
    	fs.close();
    }
    
  • 文件详情查看

    // 查看文件名称、权限、长度、块信息
    @Test
    public void testListFiles() throws IOException, InterruptedException, URISyntaxException {
    
    	// 1.获取文件系统
    	Configuration configuration = new Configuration();
    	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
    
    	// 2.获取文件详情
    	RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
    
    	while (listFiles.hasNext()) {
    		LocatedFileStatus fileStatus = listFiles.next();
    
    		System.out.println("========" + fileStatus.getPath() + "=========");
    		System.out.println(fileStatus.getPermission());
    		System.out.println(fileStatus.getOwner());
    		System.out.println(fileStatus.getGroup());
    		System.out.println(fileStatus.getLen());
    		System.out.println(fileStatus.getModificationTime());
    		System.out.println(fileStatus.getReplication());
    		System.out.println(fileStatus.getBlockSize());
    		System.out.println(fileStatus.getPath().getName());
    
    		// 获取块信息
    		BlockLocation[] blockLocations = fileStatus.getBlockLocations();
    		System.out.println(Arrays.toString(blockLocations));
    	}
    	// 3.关闭资源
    	fs.close();
    }
    
  • 文件和文件判断

    @Test
    public void testListStatus() throws IOException, InterruptedException, URISyntaxException{
    
        // 1.获取文件配置信息
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "user");
    
        // 2.判断是文件还是文件夹
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
    
        for (FileStatus fileStatus : listStatus) {
    
            // 如果是文件
            if (fileStatus.isFile()) {
                System.out.println("f:"+fileStatus.getPath().getName());
            }else {
                System.out.println("d:"+fileStatus.getPath().getName());
            }
        }
    
        // 3.关闭资源
        fs.close();
    }
    
  • 综合

    package com.zimo.hdfs;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.*;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Arrays;
    
    public class HdfsClient {
    
        private FileSystem fileSystem;
    
        @Before
        public void init() throws URISyntaxException, IOException, InterruptedException {
            // 连接的集群nn地址
            URI uri = new URI("hdfs://hadoop102:8020");
            // 创建一个配置文件
            Configuration configuration = new Configuration();
            // 用户
            String user = "zimo";
    
            // 1. 获取到客户端对象
            fileSystem = FileSystem.get(uri, configuration, user);
        }
    
        @After
        public void close() throws IOException {
            // 3. 关闭资源
            fileSystem.close();
        }
    
        // 创建目录
        @Test
        public void testmkdir() throws URISyntaxException, IOException, InterruptedException {
            // 2. 创建一个文件
            fileSystem.mkdirs(new Path("/xiyou/huaguoshan"));
        }
    
        // 上传
        @Test
        public void testPut() throws IOException {
            // para1--是否删除原数据;para2--是否允许覆盖;para3--原数据路径;para4--目的地路径
            fileSystem.copyFromLocalFile(true, true, new Path("F:\\sunwukong.txt"), new Path("/xiyou/huaguoshan"));
        }
    
        // 下载
        @Test
        public void testGet() throws IOException {
            // para1--是否删除原数据;para2--源文件路径,即HDFS路径;para3--目标地址路径,即Win路径;para4--目的地路径
            fileSystem.copyToLocalFile(false, new Path("/xiyou/huaguoshan"), new Path("F:\\"), false);
        }
    
        // 删除
        @Test
        public void testRm() throws IOException {
            // para1--删除原路径;para2--是否递归删除;
            fileSystem.delete(new Path("/jinguo"), true);
        }
    
        // 文件的更名和移动
        @Test
        public void testMv() throws IOException {
            // para1--原文件路径;para2--目标文件路径;
            fileSystem.rename(new Path("/input/word.txt"), new Path("/input/demo.txt"));
        }
    
        // 获取文件详情信息
        @Test
        public void fileDetail() throws IOException {
            // 获取所有文件信息,para1--查看文件的路径;para2--是否递归;
            RemoteIterator<LocatedFileStatus> listFiles = fileSystem.listFiles(new Path("/"), true);
            // 遍历文件
            while (listFiles.hasNext()) {
                LocatedFileStatus fileStatus = listFiles.next();
                System.out.println("======" + fileStatus.getPath() + "======");
                System.out.println(fileStatus.getPermission());
                System.out.println(fileStatus.getOwner());
                System.out.println(fileStatus.getGroup());
                System.out.println(fileStatus.getLen());
                System.out.println(fileStatus.getModificationTime());
                System.out.println(fileStatus.getReplication());
                System.out.println(fileStatus.getBlockSize());
                System.out.println(fileStatus.getPath().getName());
                // 获取块信息
                BlockLocation[] blockLocations = fileStatus.getBlockLocations();
                System.out.println(Arrays.toString(blockLocations));
            }
        }
    
        // 判断是文件还是文件夹
        @Test
        public void testFile() throws IOException {
            FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/"));
    
            for (FileStatus fileStatus : fileStatuses) {
                if (fileStatus.isFile()) {
                    System.out.println("文件:" + fileStatus.getPath().getName());
                } else {
                    System.out.println("目录:" + fileStatus.getPath().getName());
                }
            }
        }
    }
    
API总结
  • Configuration类--org.apache.hadoop.fs
    该类的对象封装了配置信息
  • FileSystem类--org.apache.hadoop.fs
    文件系统类,可使用该类的方法树对文件/目录进行操作,一般通过FileSystem的静态方法get获得一个文件系统对象
  • FSDataInputStream和FSDataOutputStream类--org.apache.hadoop.fs
    HDFS中的输入输出流。分别通过FileSystem的open方法和create方法获得
posted @   昼长  阅读(10)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示