Hadoop之hdfs 的api操作

1、获取指定目录下的全部文件及文件夹

    /**
     * 列出 {@param path} 下的文件和文件夹
     *
     * @param fs   文件系统实例
     * @param path 路径
     * @return 返回一个目录列表
     * @throws IOException 对于任何IO错误
     */
    public static List<String> listFileAndDir(FileSystem fs, Path path) throws IOException {
        List<String> list = new ArrayList<>();
        if (fs.exists(path)) {
            FileStatus[] listStatus = fs.listStatus(path);
            for (FileStatus status : listStatus) {
                list.add(status.getPath().toString());
            }
        }
        return list;
    }

2、将本地文件拷贝到HDFS上

    /**
     * 将本地文件拷贝到hdfs上
     *
     * @param fs        文件系统实例
     * @param delSrc    是否删除原文件
     * @param src       原文件路径
     * @param dst       目标文件路径
     * @param overwrite 是否覆盖现有文件
     * @throws IOException 对于任何IO错误
     */
    public static void localCopyHDFS(FileSystem fs, boolean delSrc, boolean overwrite, Path src, Path dst) throws IOException {
        fs.copyFromLocalFile(delSrc, overwrite, src, dst);
    }

3、将HDFS上的文件拷贝到本地

    /**
     * 将HDFS上的文件拷贝到本地
     *
     * @param fs                    文件系统实例
     * @param delSrc                是否删除原文件
     * @param src                   原文件路径
     * @param dst                   目标文件路径
     * @param useRawLocalFileSystem 是否进行文件校验,如果使用本地文件系统也就是设置为true,就不会产生crc校验,否则就会产生crc校验
     * @throws IOException 对于任何IO错误
     */
    public static void hdfsCopyLocal(FileSystem fs, boolean delSrc, Path src, Path dst, boolean useRawLocalFileSystem) throws IOException {
        fs.copyToLocalFile(delSrc, src, dst, useRawLocalFileSystem);
    }

4、对文件或文件夹重命名

    /**
     * 对文件或对文件夹重命名
     *
     * @param fs  文件系统实例
     * @param src 要重命名的路径
     * @param dst 重命名后的新路径
     * @return true 重命名成功;false 重命名失败
     * @throws IOException 对于任何IO错误
     */
    public static boolean rename(FileSystem fs, Path src, Path dst) throws IOException {
        return fs.rename(src, dst);
    }

5、删除文件或文件夹

    /**
     * 删除文件或文件夹
     *
     * @param fs        文件系统实例
     * @param src       要删除的路径
     * @param recursive 如果是目录,设置为true,否则会抛出异常
     * @return true 删除成功;false 删除失败
     * @throws IOException 对于任何IO错误
     */
    public static boolean deleteFile(FileSystem fs, Path src, boolean recursive) throws IOException {
        return fs.delete(src, recursive);
    }

6、判断是文件还是文件夹

    /**
     * 判断是文件还是文件夹
     *
     * @param fs  文件系统实例
     * @param src 目标路径
     * @return true 文件夹;false 文件
     * @throws IOException 对于任何IO错误
     */
    public static boolean isFileOrDir(FileSystem fs, Path src) throws IOException {
        FileStatus[] status = fs.listStatus(src);
        boolean flag = false;
        for (FileStatus fileStatus : status) {
            flag = fileStatus.isDirectory();
        }
        return flag;
    }

7、查看文件详情

    /**
     * 查看文件详情
     *
     * @param fs        文件系统实例
     * @param src       文件路径
     * @param recursive 如果子目录需要递归遍历,设置为true
     * @throws IOException 对于任何IO错误
     */
    public static void fileDetails(FileSystem fs, Path src, boolean recursive) throws IOException {
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(src, recursive);
        while (listFiles.hasNext()) {
            LocatedFileStatus status = listFiles.next();
            System.out.println("文件名:" + status.getPath().getName());
            System.out.println("块大小:" + status.getBlockSize());
            System.out.println("文件副本数:" + status.getReplication());
            System.out.println("文件修改时间:" + status.getModificationTime());
            System.out.println("文件所有者:" + status.getOwner());
            System.out.println("文件所属组:" + status.getGroup());
            System.out.println("文件大小:" + status.getLen());

            // 块的位置
            BlockLocation[] locations = status.getBlockLocations();
            for (BlockLocation location : locations) {
                // 块所在的主机 例如:hadoop51
                String[] hosts = location.getHosts();
                for (String host : hosts) {
                    System.out.println(host);
                }

                // 例如:192.168.0.51:9866
                String[] names = location.getNames();
                for (String name : names) {
                    System.out.println(name);
                }

                // 获取块的起始偏移量
                System.out.println(location.getOffset());
                // 获取块的长度
                System.out.println(location.getLength());

                // 获取块的每个副本的storageID。
                // 例如:DS-5357e114-ccb7-46d5-994e-33c047853aa3
                String[] storageIds = location.getStorageIds();
                for (String storageId : storageIds) {
                    System.out.println(storageId);
                }

                // 获取块的每个副本的存储类型。
                // 例如:DISK
                // StorageType是一个枚举类型,还包括:RAM_DISK,SSD,ARCHIVE,PROVIDED
                StorageType[] storageTypes = location.getStorageTypes();
                for (StorageType storageType : storageTypes) {
                    System.out.println(storageType.name());
                }

                // 获取每个主机的网络拓扑路径列表。
                // 例如:/default-rack/192.168.0.51:9866
                String[] topologyPaths = location.getTopologyPaths();
                for (String topologyPath : topologyPaths) {
                    System.out.println(topologyPath);
                }
            }
        }
    }

8、使用IOUtils工具类,将本地文件上传到HDFS

    /**
     * HDFS 文件上传
     *
     * @param fs            文件系统实例
     * @param configuration 配置信息
     * @param src           原文件路径
     * @param dst           目标文件路径
     * @throws IOException 对于任何IO错误
     */
    public static void putFileToHDFS(FileSystem fs, Configuration configuration, File src, Path dst) throws IOException {
        // 创建输入流
        FileInputStream fis = new FileInputStream(src);

        // 获取输出流
        FSDataOutputStream fos = fs.create(dst);

        // 流对拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
    }

9、使用IOUtils工具类,将HDFS上的文件下载到本地

    /**
     * HDFS 文件下载
     *
     * @param fs            文件系统实例
     * @param configuration 配置信息
     * @param src           原文件路径
     * @param dst           目标文件路径
     * @throws IOException 对于任何IO错误
     */
    public static void getFileFromHDFS(FileSystem fs, Configuration configuration, Path src, File dst) throws IOException {
        // 获取输入流
        FSDataInputStream fis = fs.open(src);

        // 创建输出流
        FileOutputStream fos = new FileOutputStream(dst);

        // 流对拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
    }

10、下载HDFS上指定文件的某一个block

    /**
     * 下载HDFS上指定文件的某一个block
     * 验证需要在cmd命令下使用:type jdk-8u171-windows-x64.zip.part1 >> jdk-8u171-windows-x64.zip.part0, 最后把jdk-8u171-windows-x64.zip.part0重命名为jdk-8u171-windows-x64.zip
     * @param fs 文件系统实例
     * @param src 原文件路径
     * @param block 要下载那一块,从0开始
     * @param dst 目标文件路径
     * @throws IOException IO 异常
     */
    public static void readFileBlock(FileSystem fs, Path src, int block, File dst) throws IOException {
        // 获取输入流
        FSDataInputStream fis = fs.open(src);

        // 指定块的起始位置和长度
        long offset = 0; // 起始位置
        long len = 0; // 长度
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(src, false);
        while (listFiles.hasNext()) {
            LocatedFileStatus status = listFiles.next();
            // 获取文件的块位置
            BlockLocation[] blockLocations = status.getBlockLocations();

            for (int i = 0; i < blockLocations.length; i++) {
                // 指定块
                if (i == block) {
                    // 获取起始位置
                    offset = blockLocations[i].getOffset();
                    // 获取长度
                    len = blockLocations[i].getLength();
                    // 退出循环
                    break;
                }
            }
            // 退出循环
            break;
        }
        // 指定起始位置
        fis.seek(offset);

        // 创建输出流
        FileOutputStream fos = new FileOutputStream(dst);

        // 流对拷
        byte[] buf = new byte[1024]; // 1k
        // 这里的len / 1024 是因为buf定义了1k,相当于len乘以1024,假如len=134217728B=1024*1024*128,再乘以1024,就是len=137438953472B=1024*1024*1024*128=131072MB=128GB,所以要除掉
        for (long i = 0; i < len / 1024; i++) {
            fis.read(buf);
            fos.write(buf);
        }

        // 关闭资源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
    }

11、在main方法中调用

package com.hondali.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class HDFSApiOperation {
    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
        // 设置hadoop用户
        System.setProperty("HADOOP_USER_NAME", "hadoop");
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop51:9000/"), configuration, "hadoop");
        // 列出/test目录下的文件和文件夹
        List<String> list = listFileAndDir(fs, new Path("/test"));
        for (String ls : list) {
            System.out.println(ls);
        }

        // 拷贝本地文件到hdfs
        localCopyHDFS(fs, false, false, new Path("C:\\Users\\admin\\Desktop\\kaggle.txt"),new Path("/test"));

        // 将hdfs上的文件拷贝到本地
        hdfsCopyLocal(fs, false, new Path("/test/D43_DVT_LIMIT-7-31_20190802.csv"), new Path("C:\\Users\\admin\\Desktop\\D43_DVT_LIMIT-7-31_20190802.csv"),false);

        // 重命名
        System.out.println(rename(fs, new Path("/test1"), new Path("/test")) ? "重命名成功" : "重命名失败");

        // 删除文件
        System.out.println(deleteFile(fs, new Path("/test/kaggle.txt"), false) ? "删除成功" : "删除失败");

        // 判断是文件还是文件夹
        System.out.println(isFileOrDir(fs, new Path("/test")) ? "文件夹" : "文件");

        // hdfs 上传文件
        putFileToHDFS(fs, configuration, new File("C:\\Users\\admin\\Desktop\\jdk-8u171-windows-x64.zip"), new Path("/test/jdk-8u171-windows-x64.zip"));

        // 文件详情
        fileDetails(fs, new Path("/test/jdk-8u171-windows-x64.exe"), false);

        // hdfs 文件下载
        getFileFromHDFS(fs, configuration, new Path("/test/D43_DVT_LIMIT-7-31_20190802.csv"), new File("C:\\Users\\admin\\Desktop\\D43_DVT_LIMIT-7-31_20190802.csv"));

        int block = 5;
        readFileBlock(fs, new Path("/test/jdk-8u171-windows-x64.zip"), block, new File("C:\\Users\\admin\\Desktop\\jdk-8u171-windows-x64.zip.part" + block));
        fs.close();
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值