使用Hadoop 的 Java API 操纵 HDFS 文件系统

0x00: 说明

使用 Java 操作 HDFS 文件系统可以使用其对应的Java API,即对应三个 jar 依赖包:

  • hadoop-common.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\common 目录下)
  • hadoop-hdfs.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\hdfs 目录下)
  • hadoop-client.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\hdfs 目录下)

这三个 jar 包的具体名字可能根据你所安装的版本进行变化,在本文档中这三个文件名称具体如下:

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第1张图片

此处我不推荐直接通过 jar 包引入依赖支持,本文中也将不在撰写 jar 的方式引入,因为这三个jar还依赖于其他的依赖库,例如 woodstox-core 等一系列jar包,过程较为繁琐,因此本文中使用 pom 表引入对应配置,使用pom表来管理依赖后,子依赖会自动导入,不在需要我们手动引入,较为方便,pom表依赖配置如下:


  org.apache.hadoop
  hadoop-common
  2.10.1



  org.apache.hadoop
  hadoop-hdfs
  2.10.1



  org.apache.hadoop
  hadoop-client
  2.10.1

在本文中我将在宿主机使用 IDEA 创建对应工程调用虚拟机的 Java API 接口,创建基本 Java 工程在本文中将不在赘述,但请注意,在创建工程时请将系统编译方式选择为 Maven,如下图所示:

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第2张图片

0x01: 依赖导入

注意,在第三步引入后你会发现他是处于红色的错误状态,此时点击第四步刷新依赖后即可

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第3张图片

引入依赖完成后如下图所示,但因为版本问题存在相对较多的安全的漏洞提示,鼠标放在上方即可显示相关的CVE漏洞编号,但我们仅仅只是学习用途,该问题我们直接忽略

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第4张图片

该步骤完成后 pom 表中无红色文本内容时则代表已完成依赖引入

0x02: HDFS 文件创建

这里给出一段示例代码,你可以用来验证 HDFS 的 Java API 是否能正常工作。在开始前,你需要了解如下几个注意点:

  1. 我们在访问 hdfs 的时候会进行一个权限认证认证的过程,取用户名的过程是这样的:

首先读取 HADOOP_USER_NAME系统环境变量,如果不为空,那么拿它作用户名

如果为空,则读取 HADOOP_USER_NAME 这个 java 环境变量,如果继续为空,则抛出异常

因此在下方代码中,我在第 19-20 行中加了环境变量配置,如果你不想进行该配置,则可以在第 27 行文件系统配置中进行修改,添加一个user参数,代码如下:

// 链接到文件系统
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf, "root");
  1. 该段代码运行后可能会提示有找不到 logger 和 log4j 未正常初始化的配置,如下图,但因为我们此处仅作学习用途,该警告我们可直接忽略。

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第5张图片

完整实例代码如下:

package org.example;

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 java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // 创建文件
            FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path("/Tianxidev/test/1.txt"));

            // 写入文件内容到输出流
            fsDataOutputStream.writeUTF("Hi HDFS!");

            // 输出流提交 HDFS
            fsDataOutputStream.flush();

            // 关闭输出流
            fsDataOutputStream.close();

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

运行后,我们在虚拟机上执行命令 hdfs dfs -ls / 查看 HDFS 文件系统根目录,发现已多出一个我们代码中创建的文件夹,使用 hdfs dfs -cat /Tianxidev/test/1.txt 查看我们创建的文件内容发现写入内容为预期文本,此时则代表 HDFS 的 Java API 工作正常。

使用Hadoop 的 Java API 操纵 HDFS 文件系统_第6张图片

0x03: HDFS 文件夹创建

此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证

package org.example;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // 创建文件夹
            fileSystem.mkdirs(new Path("/Tianxidev/test1"));

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

0x04: 本地文件上传 HDFS

此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证

package org.example;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // 上传本地文件
            fileSystem.copyFromLocalFile(new Path("D:\\temp\\hdfs_test_1.txt"),new Path("/Tianxidev/test1"));

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

0x05: 读取 HDFS 文件内容

此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证

package org.example;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // 打开文件
            FSDataInputStream fsDataInputStream = fileSystem.open(new Path("/Tianxidev/test/1.txt"));

            // 打印文件内容
            System.out.println("文件内容: " + fsDataInputStream.readUTF());

            // 关闭输入流
            fsDataInputStream.close();

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

0x06: HDFS 文件下载本地

此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证

请注意,因为win系统文件系统结构原因,会抛出如下报错:

java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset. 

出现该报错时需要你引入 winutils 支持,winutil.exe 主要用于模拟linux下的目录环境,你可以在互联网上寻找该配置教程,如果你不想麻烦,也可以选择通过 API 读取文件内容然后在使用 Java 文件相关API方法将文件流作为文件写入系统。

package org.example;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // 下载文件到本地
            fileSystem.copyToLocalFile(new Path("/Tianxidev/test1/hdfs_test_1.txt"),new Path("D:\\temp\\hdfs_test_1.txt"));

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

0x07: 远程删除 HDFS 文件或文件夹

此处仅提供完整样例代码不在提供运行截图,样例代码已经过验证

package org.example;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;


public class Main {

    public static void main(String[] args) {

        // 配置环境变量
        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        // 创建配置
        Configuration conf = new Configuration();

        try {

            // 链接到文件系统
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.234.129:9000"), conf);

            // b: true 递归删除目录 false 删除指定文件
            fileSystem.delete(new Path("/Tianxidev/test1/hdfs_test_1.txt"),false);
            fileSystem.delete(new Path("/Tianxidev"),true);

            // 关闭文件系统
            fileSystem.close();

        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }

    }

}

你可能感兴趣的:(大数据学习笔记,hadoop,hdfs,java)