大数据分析学习第四课 使用Java idea开发hdfs的基本功能-增删改查

本文详细介绍了如何在Java环境中搭建Maven项目,引入Hadoop相关依赖,并配置HDFS的core-site.xml和hdfs-site.xml文件。通过编写Java代码,实现了HDFS的文件上传、下载、重命名、删除、追加内容、列出目录和文件信息等操作。文章提供了详细的步骤和代码示例,帮助读者理解并掌握Java操作HDFS的基本方法。
摘要由CSDN通过智能技术生成

    在上节第三课中,我们介绍了Hadoop集群使用HDFS和MapReduce,我们在介绍HDFS时,都是直接运行hadoop命令来上传文件,这节课我们介绍在java环境调用和操作HDFS的文件管理功能。

    我们知道,通过hadoop hive或spark等数据计算框架完成数据清洗后的数据是存储在HDFS上的,而爬虫和机器学习等程序在Python或java中容易实现,在Linux环境下编写Python或java程序没有那么便利,所以我们需要建立Python,Java与HDFS的读写通道。

1、建立Maven项目

首先,我们启动idea,我的版本是IntelliJ IDEA 2019.2.1 x64,点击左上角File=》New Project,弹出如下界面,我们在左侧选择Maven,然后默认jdk是1.8版本,点Next

我们输入项目信息,继续下一步

这一步我们选择maven版本,配置路径,继续下一步

好了,我们的项目已经建好并加载了,如下图,我们可以在右侧Maven界面先双击下install,让maven帮我们下载Maven项目引用的包,如下图所示

我们打开项目的pom.xml文件,加入引用hadoop相关的包,

 <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

加入引用后,我们Reimport一下,下载相关的包,下图可以看到,相关包已经下载

我们也可以在Maven面板看到依赖

2、添加hadoop配置文件

在我的第二节课,Hadoop集群安装与配置中,我们配置了5个文件,现在我们从服务器中复制出2个文件,core-site.xml和hdfs-site.xml,放到我们项目的资源目录

同时我们把resources目录设置为Resources Root

给大家看下core-site.xml,就是我第二节课的配置,没有改

3、编写测试程序

我们在java目录下,新建一个java类文件base_hdfs,加入下面的代码和引用

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.*;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class base_hdfs {
    String hdfsURL = "hdfs://master105:9000";

    FileSystem fs;
    @Before
    public void before() throws IOException, InterruptedException {
        fs = FileSystem.get(URI.create(hdfsURL), new Configuration(), "root");
    }

    @Test
    public void put() throws IOException, InterruptedException {
        //设置配置文件
        Configuration configuration = new Configuration();
//        configuration.setInt("dfs.replication",1);//副本数

        fs = FileSystem.get(URI.create(hdfsURL), configuration, "root");
        fs.copyFromLocalFile(new Path("d:\\word0326.txt"),new Path("/mydata/test/out.txt"));
    }

    @Test
    public void get() throws IOException, InterruptedException {
        Configuration configuration = new Configuration();
        FileSystem fileSystem = FileSystem.get(URI.create(hdfsURL), configuration, "root");
//        fileSystem.copyFromLocalFile(new Path("E:\\a.txt"),new Path("/"));
        fileSystem.copyToLocalFile(new Path("/jdk8"),
                new Path("d:\\"));
        fileSystem.close();
    }

    //修改名字
    @Test
    public void rename() throws IOException, InterruptedException {
        //1、获取文件系统
        FileSystem fileSystem = FileSystem.get(URI.create(hdfsURL), new Configuration(), "root");
        fileSystem.rename(new Path("/mydata/test/out.txt"),new Path("/mydata/test/out0324.txt"));
        fileSystem.close();
    }

      //删除
    @Test
    public void detele() throws IOException {
        boolean delete = fs.delete(new Path("/mydata/test/out0324.txt"), true);
        if (delete){
            System.out.println("删除成功!");
        }else{
            System.out.println("删除失败!");
        }
    }
     @Test
    public void append() throws IOException {
        FSDataOutputStream append = fs.append(new Path("/mydata/test/out.txt"), 1024);
//        FSDataInputStream open = fs.open(new Path("/a.txt"));
        final FileInputStream open = new FileInputStream("e:\\a.txt");
        IOUtils.copyBytes(open,append,1024,true);
    }
    @Test
    public void ls() throws IOException {
        FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : fileStatuses) {
            boolean file = fileStatus.isFile();

            //如果是文件
            if (file){
                System.out.println(fileStatus.getPath());
                System.out.println(fileStatus.getLen());
            }else{
                System.out.println("这是一个文件夹");
                System.out.println(fileStatus.getPath());
            }

        }
    }
     @Test
    public void listFiles() throws IOException {
        RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("/"), true);
        while (files.hasNext()){
            LocatedFileStatus file = files.next();
            System.out.println("====================");
            System.out.println(file.getPath());

            BlockLocation[] blockLocations = file.getBlockLocations();
            System.out.println("块信息:");
            for (BlockLocation blockLocation : blockLocations) {
                String[] hosts = blockLocation.getHosts();
                System.out.print("块在:");
                for (String host : hosts) {
                    System.out.print(host);
                }

            }

        }
    }

     @After
    public void after() throws IOException {
        fs.close();
    }

}

在上面的代码中,我们使用了junit进行单元测试,在测试方法前,我们定义了befor和after,

在一个JUnit4的单元测试用例执行顺序为: 
@BeforeClass -> @Before -> @Test -> @After -> @AfterClass; 
每一个测试方法的调用顺序为: 

@Before -> @Test -> @After; 

所以我们每执行一次测试方法,都会先调用befer打开HDFS连接,执行完后都会调用after关闭连接

接下来我们分别执行各个方法

1)上传文件put,我们在根目录指定了一个路径 /mydata/test/,我们刷新下http://master105:50070/explorer.html#/

可以看到文件已经上传

2)下载文件get

我们把之前测试上传的jdk8下载到本地d:\test下面,可以看到下载成功

3)修改文件名字rename,我们把刚才上传的文本out.txt改名为out0324.txt

执行后,我们刷新下文件管理页面,可以看到文件名已经修改

4)删除hdfs文件

我们执行删除刚才改名的文件,刷新管理页面,文件已经删除

5)追加文件内容append,我们先执行刚才的上传方法put,把out文件上传到/mydata/test目录,文本里面内容是

我们准备一个追加文件test.txt,内容是

 

我们执行append方法后,把服务器上的文件下载打开,可以看到文本已经加进去了

如果遇到下面的错误,不要慌,我们需要修改下配置文件

我们修改hdfs-site.xml文件,这里需要注意,我们既要修改集群里的文件,也要修改maven项目里的,我们加上配置

    <property>
        <name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
        <value>NEVER</value>
    </property>

加完配置后,我们需要重启集群生效,然后在执行append方法就可以追加成功了

6)列出目录ls,我们这里是列出根目录 /,可以看到打印输出

7)列出文件信息listFiles,我们这里是列出根目录 / 下面文件所在服务器和块信息,可以看到打印输出

以上就是在java下操作HDFS的常用方法,还有更多方法可以去官网参考

总结
        感谢能看到这里的朋友😉

        本次的分享就到这里,猫头鹰数据致力于为大家分享技术干货😎

        如果以上过程中出现了任何的纰漏错误,烦请大佬们指正😅

        受益的朋友或对技术感兴趣的伙伴记得点赞关注支持一波🙏

        也可以搜索关注我的微信公众号【猫头鹰数据分析】,留言交流🙏

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫头鹰数据分析

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值