您现在的位置是:首页 >技术教程 >Hadoop框架-HDFS-客户端API操作网站首页技术教程

Hadoop框架-HDFS-客户端API操作

丷江南南 2023-06-19 16:00:02
简介Hadoop框架-HDFS-客户端API操作

一.客户端代码常用套路

客户端代码的常用套路分为以下三步:
1.获取一个客户端对象FileSystem
2.执行相关操作命令
3.关闭客户端对象

当然,在执行以上操作前,首先要确保Hadoop集群处于打开状态:
请添加图片描述

接下来便可以按照以上步骤进行API操作:

1.获取一个客户端对象FileSystem

当我们通过new的方式构造FileSystem对象时,出现了如下编译错误

请添加图片描述

通过追溯源码我们发现FileSystem原来是一个抽象类,故而无法通过new的方式实例化对象:

请添加图片描述

因此我们转而通过get的方式来获取FileSystem对象:

请添加图片描述
这里get方法需要传入3个参数:
1.URI url: 连接的集群的namenode地址。由于我们把namenode节点放在了Hadoop102服务器上,并且HDFS在hadoop的内部通讯端口为:8020,使用了HDFS传输协议,故此参数设为:“hdfs://hadoop102:8020
2.Configuration conf: 配置文件。这里直接通过new方式来获取所需的配置信息
3.String user: 用户id。如果不写的话,对文件将没有权限执行操作

接下来便可以编写代码了,为了方便后续使用,我们把获取客户端FileSystem对象的内容以一个init方法的形式封装起来,避免冗余的操作:

请添加图片描述

这里我们通过ctrl+alt+f命令把FileSystem对象升级为类中的一个全局变量(因为后续我们把关闭对象的操作也封装到了类中的另一方法内,关闭时需要调用该对象)

2.执行相关操作命令

此处可以直接跳到第二章节案例实操查看!!!

3.关闭客户端对象

同样,关闭资源的操作我们也封装到一个close方法内:
请添加图片描述

二、HDFS的API案例实操

1.创造目录 mkdirs

通过调用mkdirs方法即可创造一个目录:

请添加图片描述

注意这里我们为mkdirs方法传入的参数仅为1个Path对象,而Path对象内传入的即为要创造的目录路径

代码如下:

@Test
    public void testmkdir() throws URISyntaxException, IOException, InterruptedException {
        fs.mkdirs(new Path("/fusir/qinqin"));
    }

注:由于我们这里是Test测试方法,并使用了Junit注解规定了该方法会在Before方法(获取客户端FileSystem对象)之后执行,并在After方法(关闭客户端FileSystem对象)之前执行,所以只需要写需要执行的操作的代码即可。

运行之后,我们在Web端查看HDFS的namenode信息,可以看到新目录已创建:

注:查看Web端的网址:http://hadoop102:9870/

请添加图片描述
请添加图片描述

2.上传文件到HDFS客户端 CopyFromLocalFile

通过调用CopyFromLocalFile方法可从本地上传文件Hadoop客户端

注:和Shell命令操作不同,客户端不能通过put方法上传文件

请添加图片描述
该方法共有4个参数,其中分别代表:
boolean delSrc: 是否删除源数据

boolean overwirte: 是否允许覆盖

Path src: 源数据路径

Path dst: 目的地路径

给定一个需求:从本地上传指定文件至客户端,同时删除本地文件,步骤如下:

首先在本地创建a.txt文件:
请添加图片描述
接着运行如下代码开始上传:

@Test
    public void testPut() throws IOException {
        fs.copyFromLocalFile(true,false,new Path("D:/timu/a.txt"),new Path("/fusir/qinqin"));
    }

查看本地端发现a.txt已被删除:
请添加图片描述
查看客户端发现/fusir/qinqin目录下已有内容被上传:
请添加图片描述

3.下载文件到本地 CopyToLocalFile

通过调用CopyToLocalFile方法可把Hadoop客户端的文件下载本地

注:和Shell命令操作不同,客户端不能通过get方法下载文件

请添加图片描述
该方法同样也有4个参数,其中分别代表:
boolean delSrc: 是否删除源文件

Path src: 源文件路径

Path dst: 目的地路径

boolean useRawLocalFileSystem: 是否进行文件校验

给定一个需求:把客户端上的指定文件下载到本地,不删除客户端文件且不开启文件校验,代码如下:

@Test
    public void testGet() throws IOException {
        fs.copyToLocalFile(false,new Path("/MyJavaLearn/xixi.txt"),new Path("D:/timu/b.txt"),false);
    }

查看本地端发现文件已下载:
请添加图片描述
查看客户端发现源文件没有被删除:
请添加图片描述

注:如果不进行校验,本地端会在下载源文件的同时生成一个crc文件;如果进行校验,则该crc文件不会产生。

4.删除文件 delete

通过调用delete方法可把Hadoop客户端文件删除

请添加图片描述

该方法有2个参数,其中分别代表:
Path path: 要删除的路径

boolean b: 是否递归删除

给定一个需求:删除客户端的fusir目录,要求递归删除其下所有文件与目录,代码如下:

@Test
    public void testDelete() throws IOException {
        fs.delete(new Path("/fusir"),true);
    }

查看客户端发现源路径已消失:

请添加图片描述

给定另一需求:删除客户端MyJavaLearn目录下的指定文件,代码如下:

@Test
    public void testDelete() throws IOException {
        fs.delete(new Path("/MyJavaLearn/xixi.txt"),false);
    }

查看客户端发现源文件已消失:
请添加图片描述

5.更名与移动 rename

通过调用rename方法可对Hadoop客户端文件进行更名或移动

请添加图片描述

该方法有2个参数,其中分别代表:
Path path: 源文件路径

Path path1: 目标文件路径

给定一个需求:把客户端的MyJavaLearn目录更名为mylearn:

更名前客户端:
请添加图片描述
运行代码:

@Test
    public void testMv() throws IOException {
        fs.rename(new Path("/MyJavaLearn"),new Path("/mylearn"));
    }

更名后客户端:

请添加图片描述

给定另一需求:把客户端mylearn目录下的指定文件移动到主目录下:

移动前客户端:

请添加图片描述
请添加图片描述
运行如下代码:

@Test
    public void testDelete() throws IOException {
        fs.delete(new Path("/MyJavaLearn/xixi.txt"),false);
    }

移动后客户端,可以看到文件已被转移到主目录下:
请添加图片描述
请添加图片描述

6.查看文件详情 listFiles

通过调用listFiles方法可在本地获取Hadoop客户端指定路径下的所有文件信息

请添加图片描述

该方法有2个参数,其中分别代表:

Path f: 要查找的路径

boolean recursive: 是否递归查找

给定一个需求:查找客户端主目录下所有文件的信息详情,要求递归查找:

@Test
    public void testListFiles() throws IOException {
        //获取所有文件信息
        RemoteIterator<LocatedFileStatus> listfiles = fs.listFiles(new Path("/"), true);
        //遍历迭代器
        while (listfiles.hasNext()) {
            LocatedFileStatus next = listfiles.next();
            System.out.println("========"+next.getPath()+"========");
            //获取文件的访问权限
            System.out.println(next.getPermission());
            //获取文件属主
            System.out.println(next.getOwner());
            //获取文件属组
            System.out.println(next.getGroup());
            //获取文件长度
            System.out.println(next.getLen());
            //获取文件最近一次的修改时间
            System.out.println(next.getModificationTime());
            //获取文件的副本数
            System.out.println(next.getReplication());
            //获取文件的块大小
            System.out.println(next.getBlockSize());
            //获取文件名
            System.out.println(next.getPath().getName());
            
            //获取块信息
            BlockLocation[] loc = next.getBlockLocations();
            System.out.println(Arrays.toString(loc));
        }
    }

控制台的部分输出如下:
请添加图片描述

7.判断是文件/文件夹 listStatus

通过调用listStatus方法,可递归遍历客户端指定路径下的所有数据,

请添加图片描述
该方法的唯一参数Path path传入的是要判断的路径。

给定一个需求:判断客户端指定路径为文件还是文件夹:

请添加图片描述
请添加图片描述

@Test
    public void testFile() throws IOException {
        FileStatus[] listStatus = fs.listStatus(new Path("/mylearn"));
        for (FileStatus status : listStatus) {
            if (status.isFile()) {
                System.out.println("文件:"+status.getPath().getName());
            }else{
                System.out.println("路径:"+status.getPath().getName());

                }
            }
        }

控制台输出为:
请添加图片描述

@Test
   @Test
    public void testFile() throws IOException {
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus status : listStatus) {
        	//判断是否为文件
            if (status.isFile()) {
                System.out.println("文件:"+status.getPath().getName());
            }//判断是否为目录
             else if (status.isDirectory()) {
                System.out.println("目录:"+status.getPath().getName());
            }
            }
        }
}

控制台输出为:

请添加图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。