大数据 | Java 操作 HDFS 常用 API

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 大数据 | Java 操作 HDFS 常用 API

        上篇文章介绍了关于 HDFS 的常用命令,其常用的命令都有相应的 API,用命令可以完成的功能,使用 Java API 也可以完成。本文介绍关于 HDFS 常用的 Java API。

一、回顾常用的命令

       在上篇文章中整理了 HDFS 常用的命令,这里进行简单的回顾。

       ls 命令用来查看 HDFS 系统中的目录和文件,命令如下:

$ hadoop fs -ls /

     put 命令用来将本地文件上传到 HDFS 系统中,命令如下:

$ hadoop fs -put test.txt /

       moveFromLocal 命令将本地文件移动到 HDFS 文件系统中,并将本地的文件进行删除,命令如下:

$ hadoop fs -moveFromLocal abc.txt /


       moveFromLocal 命令将本地文件移动到 HDFS 文件系统中,并将本地的文件进行删除,命令如下:

$ hadoop fs -moveFromLocal abc.txt /

       rm 命令用来删除 HDFS 系统中的文件或文件夹,命令如下

$ hadoop fs -rm /test.txt

       mkdir 命令用来在 HDFS 系统中创建目录,命令如下:

$ hadoop fs -mkdir /test

       cp 命令在 HDFS 系统中用于文件的复制,命令如下:

$ hadoop fs -ls /

     mv 命令在 HDFS 系统中用于完成文件移动的功能,也可以用来进行文件的重命名功能,命令如下:

$ hadoop fs -mv /abc/abc.txt /test/
$ hadoop fs -mv /test/abc.txt /test/abcabc.txt

       cat 命令在 HDFS 文件系统中用于输出某个文件的内容,命令如下:

$ hadoop fs -cat /test/abcabc.txt

       appendToFile 命令将单个或多个文件的内容从本地系统中追加到 HDFS 系统的文件中,命令如下:

$ hadoop fs -appendToFile abc.txt /abc.tx

       上面的内容简单的对 HDFS 文件系统的常用命令进行了回顾,接下来,我们来整理一下关于 HDFS 常用的 Java API。

二、引入依赖

       使用 HDFS 的 Java API 可以操作 HDFS 文件系统中的文件,比如文件的新建、删除、读取等。创建一个 Maven 的项目,然后引入其依赖,准备工作就算是完成了,依赖如下:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.8.2</version>
</dependency>


       引入该依赖后,在 HDFS 的 Java API 中使用 FileSystem 工具类,它可以完成我们的操作,下面我们来进行了解。

三、文件列表

      代码非常的简单,因此这里直接上代码,代码如下:

public static void main(String[] args) throws IOException {
    Configuration conf = new Configuration();
    // 设置 HDFS 访问地址
    conf.set("fs.default.name", "hdfs://centos01:9000");
    // 取得 FileSystem 文件系统实例
    FileSystem fs = FileSystem.get(conf);
    List<String> filesUnderFolder = HdfsFileSystem.getFileList(fs, new Path("hdfs:/"));
    filesUnderFolder.forEach(System.out::println);
}
public static List<String> getFileList(FileSystem fs, Path folderPath) throws IOException {
    List<String> paths = new ArrayList();
    if (fs.exists(folderPath)) {
        FileStatus[] fileStatus = fs.listStatus(folderPath);
        for (int i = 0; i < fileStatus.length; i++) {
            FileStatus fileStatu = fileStatus[i];
            paths.add(fileStatu.getPath().toString());
        }
    }
    return paths;
}

       上面的代码中,在自定义的方法 getFileList 中通过 FileSystem 类的 listStatus() 方法返回了 HDFS 文件系统 / 目录下的所有文件和目录,输出内容如下:

hdfs://centos01:9000/abc
hdfs://centos01:9000/abc.txt
hdfs://centos01:9000/depInput
hdfs://centos01:9000/depOutput
hdfs://centos01:9000/input
hdfs://centos01:9000/output
hdfs://centos01:9000/scoreInput
hdfs://centos01:9000/scoreOutput
hdfs://centos01:9000/secondInput
hdfs://centos01:9000/secondOutput
hdfs://centos01:9000/test
hdfs://centos01:9000/tmp

      上面的输出则是我虚拟机中 HDFS 中的文件列表。如果需要显示其他目录下的文件和目录列表,只需要传入相应的路径即可。如果要显示全部文件,只需要判断是否为目录,如果为目录直接递归调用就可以了。

四、创建目录

       创建目录使用 FileSystem 类的 mkdirs 方法即可完成,代码如下:

public static void main(String[] args) throws IOException {
    String path = "hdfs:/hdfsDir";
    HdfsFileSystem.createDir(path);
}
/**
 * 创建 HDFS 目录 mydir
 */
public static void createDir(String pathString) throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://centos01:9000");
    org.apache.hadoop.fs.FileSystem fs = org.apache.hadoop.fs.FileSystem.get(conf);
    // 创建目录
    boolean created = fs.mkdirs(new Path(pathString));
    if (created) {
        System.out.println("创建目录成功");
    } else {
        System.out.println("创建目录失败");
    }
    fs.close();
}

       mkdirs 方法的返回类型是 boolean 类型,返回 true 表示创建成功,返回 false 表示创建失败。使用 HDFS 的命令来进行查看,命令如下:

$ hadoop fs -ls / | grep hdfsDir
drwxr-xr-x   - Administrator supergroup          0 2021-11-12 10:09 /hdfsDir

       可以看到,/hdfsDir 目录被创建成功。

五、文件的创建

       文件的创建使用 FileSystem 类的 create 方法即可完成文件的创建,代码如下:

public static void main(String[] args) throws IOException {
    String path = "hdfs:/fileAbc.txt";
    String context = "1234";
    HdfsFileSystem.createFile(path, context);
}
/**
 * 定义创建文件方法
 */
public static void createFile(String pathString, String context) throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://centos01:9000");
    FileSystem fs = FileSystem.get(conf);
    // 打开一个输出流
    FSDataOutputStream outputStream = fs.create(new Path(pathString));
    // 写入文件内容
    outputStream.write(context.getBytes());
    outputStream.close();
    fs.close();
    System.out.println("文件创建成功");
}

       上面的代码在 HDFS 的根目录下创建了一个名为 fileAbc.txt 的文件,并向文件内写入了 1234 这样的内容,通过命令来查看该文件是否创建成功,内容是否写入成功,命令如下:

$ hadoop fs -ls / | grep fileAbc
-rw-r--r--   3 Administrator supergroup          4 2021-11-12 10:17 /fileAbc.txt
$ hadoop fs -cat /fileAbc.txt
1234

六、文件内容的输出

       文件内容的输出使用 FileSystem 类的 open 方法,使用输入流进行读取即可。代码如下:

public static void main(String[] args) throws IOException {
    String path = "hdfs:/fileAbc.txt";
    HdfsFileSystem.fileSystemCat(path);
}
/**
 * 查询 HDFS 文件内容并输出
 */
public static void fileSystemCat(String pathString) throws IOException {
    Configuration conf = new Configuration();
    // 设置 HDFS 访问地址
    conf.set("fs.default.name", "hdfs://centos01:9000");
    // 取得 FileSystem 文件系统实例
    FileSystem fs = FileSystem.get(conf);
    // 打开文件输入流
    InputStream in = fs.open(new Path(pathString));
    // 输出文件内容
    IOUtils.copyBytes(in, System.out, 4096, false);
    // 关闭输入流
    IOUtils.closeStream(in);
}

    运行代码即可看到文件的内容被输出,输出如下:

1234

七、删除文件

       文件的删除使用 FileSystem 类的 deleteOnExit 方法,代码如下:

public static void main(String[] args) throws IOException {
    String path = "hdfs:/fileAbc.txt";
    HdfsFileSystem.deleteFile(path);
}
/**
 * 删除文件
 */
public static void deleteFile(String pathString) throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://centos01:9000");
    FileSystem fs = FileSystem.get(conf);
    Path path = new Path(pathString);
    // 删除文件
    boolean isok = fs.deleteOnExit(path);
    if (isok) {
        System.out.println("删除成功");
    } else {
        System.out.println("删除失败");
    }
    fs.close();
}

       通过命令进行查看,文件已经被删除了。

八、读取文件/目录的元数据

       读取文件/目录的元数据使用 FileSystem 类的 getFileStatus 方法即可完成,代码如下:

public static void main(String[] args) throws IOException {
    String path = "hdfs:/fileAbc.txt";
    String context = "1234";
    HdfsFileSystem.createFile(path, context);
    HdfsFileSystem.fileStatusCat(path);
}
/**
 * 获取文件或目录的元数据信息
 */
public static void fileStatusCat(String pathString) throws IOException {
    // 创建 Configuration 对象
    Configuration conf = new Configuration();
    // 设置 HDFS 访问地址
    conf.set("fs.default.name", "hdfs://centos01:9000");
    // 取得 FileSystem 文件系统实例
    FileSystem fs = FileSystem.get(conf);
    FileStatus fileStatus = fs.getFileStatus(new Path(pathString));
    // 判断是文件夹还是文件
    if (fileStatus.isDirectory()) {
        System.out.println("这是一个文件夹");
    } else {
        System.out.println("这是一个文件");
    }
    // 输出元数据信息
    System.out.println("文件路径:" + fileStatus.getPath());
    System.out.println("文件修改日期:" + new Timestamp(fileStatus.getModificationTime()).toString());
    System.out.println("文件上次访问日期:" + new Timestamp(fileStatus.getAccessTime()).toString());
    System.out.println("文件长度:" + fileStatus.getLen());
    System.out.println("文件备份数:" + fileStatus.getReplication());
    System.out.println("文件块大小:" + fileStatus.getBlockSize());
    System.out.println("文件所有者:" + fileStatus.getOwner());
    System.out.println("文件所在分组:" + fileStatus.getGroup());
    System.out.println("文件的权限:" + fileStatus.getPermission().toString());
}

       通过 FileStatus 可以得到文件的各种信息,上面的输出内容如下:

这是一个文件
文件路径:hdfs://centos01:9000/fileAbc.txt
文件修改日期:2021-11-12 11:02:12.797
文件上次访问日期:2021-11-12 11:02:12.438
文件长度:4
文件备份数:3
文件块大小:134217728
文件所有者:Administrator
文件所在分组:supergroup
文件的权限:rw-r--r--

       这里,我们获取了文件的路径、修改日期、上次访问日期、文件长度等信息。

九、上传本地文件到 HDFS

       上传文件使用 FileSystem 类的 copyFromLocalFile 即可完成,代码如下:

public static void main(String[] args) throws IOException {
    HdfsFileSystem.uploadFileToHDFS("d:/mysql.docx", "hdfs:/");
}
/**
 * 上传本地文件到 HDFS
 */
public static void uploadFileToHDFS(String srcPath, String dstPath) throws IOException {
    // 创建配置器
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://centos01:9000");
    // 取得 FileSystem 文件系统实例
    FileSystem fs = FileSystem.get(conf);
    // 创建可供 hadoop 使用的文件系统路径
    // 本地目录/文件
    Path src = new Path(srcPath);
    // HDFS 目录/文件
    Path dst = new Path(dstPath);
    // 复制上传文帝文件至 HDFS 文件系统中
    fs.copyFromLocalFile(src, dst);
    System.out.println("文件上传成功");
}

     通过命令来查看上传的情况,命令如下:

$ hadoop fs -ls / | grep mysql
-rw-r--r--   3 Administrator supergroup    1470046 2021-11-12 11:06 /mysql.docx

十、下载 HDFS 文件到本地

       下载 HDFS 文件到本地使用 FileSystem 类的 copyToLocalFile 方法即可,代码如下:

public static void main(String[] args) throws IOException {
    HdfsFileSystem.downloadFileToLocal("hdfs:/mysql.docx", "d:/test.docx");
}
/**
 * 下载文件到本地
 */
public static void downloadFileToLocal(String srcPath, String dstPath) throws IOException {
    // 创建配置器
    Configuration conf = new Configuration();
    conf.set("fs.default.name", "hdfs://centos01:9000");
    // 取得 FileSystem 文件系统实例
    FileSystem fs = FileSystem.get(conf);
    // 创建可供 hadoop 使用的文件系统路径
    Path src = new Path(srcPath);
    Path dst = new Path(dstPath);
    // 从 HDFS 文件系统中复制下载文件至本地
    fs.copyToLocalFile(false, src, dst, true);
    System.out.println("文件下载成功");
}

       到本地的 D 盘进行查看,文件已经下载成功。

十一、总结

       HDFS 是 Hadoop 项目中的核心模块,使用 HDFS 的 Java API 操作 HDFS 非常的方便也比较简单。不知道大家注意到了么,HDFS 作为文件系统,它可以完成对 文件的 增加、追加、删除、查看 等功能,但是,竟然没有对文件进行修改的功能。这是 HDFS 有别于其他文件系统的一个特点,HDFS 的作者是出于什么样的目的如此设计呢?留着以后讨论吧!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
2月前
|
分布式计算 Kubernetes Hadoop
大数据-82 Spark 集群模式启动、集群架构、集群管理器 Spark的HelloWorld + Hadoop + HDFS
大数据-82 Spark 集群模式启动、集群架构、集群管理器 Spark的HelloWorld + Hadoop + HDFS
181 6
|
2月前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
56 0
|
8天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
67 34
|
9天前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
40 10
|
17天前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
18天前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
24 0
|
1月前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
2月前
|
分布式计算 大数据 Java
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
36 1
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
|
1月前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。

热门文章

最新文章