Java API 操作 HDFS 文件系统

特别提示

  1. 执行前需要启动 hadoop
  2. IDEA创建Hadoop-Maven项目
  3. 下载 hadoop.dll 放入windows的C:\Windows\System32

相关环境

  1. windows10
  2. hadoop 2.9.2 伪分布式搭建
  3. idea 2018.3.5

0x00 JAVA 连接 HDFS

  • 配置连接
public static final String HDFS_PATH = "hdfs://192.168.5.137:9000";  // HDFS 路径

FileSystem fileSystem = null;       // 操作文件系统 注意选中 apache 的类
Configuration configuration = null; //  HDFS 配置连接
  • 创建连接方法
@Before  // 所有执行完之前执行
public void setUp() throws Exception{
    configuration = new Configuration(); // 实例化类
    fileSystem = FileSystem.get(new URI(HDFS_PATH),configuration,"root"); // 参数 :路径 配置类 用户
}

0x01 执行结束时释放资源

@After  // 所有执行完之后再执行
public void tearDown() throws Exception{
      // 结束释放资源
      configuration = null;
      fileSystem = null;
}

0x02 创建文件夹

@Test  // 单元测试
public void mkidr() throws Exception{
    fileSystem.mkdirs(new Path("/HDFSAPI/test"));
}

0x03 删除文件操作

@Test
public void delete() throws Exception{
    // 参数:路径 递归删除
    boolean msg = fileSystem.delete(new Path("/HDFSAPI/test/a.txt"),true);
}

0x04 创建文件并写入内容

@Test // 单元测试
public void create() throws Exception{
    // 返回值 是一个文件流
    FSDataOutputStream output=fileSystem.create(new Path("/HDFSAPI/test/e.txt"));
    // 通过流写入一个 Bytes[] 数组
    output.write("hello hadoop".getBytes());
    output.flush();
    // 把文件流关闭
    output.close();
}

0x05 查看文件内容

@Test // 单元测试
public void cat() throws Exception{
    FSDataInputStream file = fileSystem.open(new Path("/HDFSAPI/test/e.txt"));
    // 把内容输出到控制台 使用 hadoop 里的类
    IOUtils.copyBytes(file , System.out , 1024); // 文件内容对象 输出到控制台 缓冲区大小
    // 关闭
    file.close();
}

0x06 文件的重命名

@Test // 单元测试
public void rename() throws Exception{
     // 旧文件的路径
     Path oldPath = new Path("/HDFSAPI/test/a.txt");
     // 新文件的路径
     boolean msg = fileSystem.rename(oldPath,newPath);
}

0x07 本地上传文件到 HDFS

@Test
public void copyFromLocalFile() throws Exception{
    // 本地路径 ---> 我是在 windows上测试的 所以是如下地址
    Path LocalPath = new Path("D://data.txt");
    // 上传到 HDFS 上的路径
    Path HDFSPath = new Path("/HDFSAPI/test/");
    fileSystem.copyFromLocalFile(LocalPath,HDFSPath);
}

0x08 大文件上传带进度条提示

@Test
public void copyFromLocalFileWithProgress() throws Exception{
    // 获取需要上传的文件
    InputStream file = new BufferedInputStream(  // 为了提升效率 使用 Buffer
             new FileInputStream(               // 需要把 File 转换为 Stream
                    new File("F://BigData/hadoop/hadoop-2.9.2.tar.gz")));

    // 创建上传的文件路径
    FSDataOutputStream output=fileSystem.create(
            new Path("/HDFSAPI/test/newhadoop-2.9.2.tar.gz"), // 第一个参数 可以进行重命名
            new Progressable() {                                         // 第二个参数 打印的进度条
                @Override
                public void progress() {
                    System.out.print("*");  // 提示的进度条图案
                }
             }
    );
    // 上传
    IOUtils.copyBytes(file,output,4096);
}

mark

0x09 下载文件

@Test
public void copyToLocalFrom() throws Exception{
     Path hdfsPath = new Path("/HDFSAPI/test/a.txt");
     // 本地路径
     Path localPath = new Path("F://a.txt");
     fileSystem.copyToLocalFile(hdfsPath,localPath);
}

0x10 查看目录下的所有文件

@Test
public void listFile() throws Exception{
    // 需要查看的 hdfs 目录
    Path hdfsPath = new Path("/HDFSAPI/test");
    FileStatus[] fileStatuses = fileSystem.listStatus(hdfsPath);
    for(FileStatus file : fileStatuses){
        // 输出路径
        String filePath = file.getPath().toString();
        // 查看是否是目录
        String isDir = file.isDirectory() ? "文件夹" : "文件";
        // 输出文件大小
        long fileSize = file.getLen();
        // 输出文件的副本数量
        short fileReplication = file.getReplication();
        // 输出打印
        System.out.println(filePath+"\t"+isDir+"\t"+fileSize+"\t"+fileReplication+"\t");
    }
}

mark

常见问题

  1. org.apache.hadoop.util.NativeCrc32.nativeComputeChunkedSumsByteArray(II[BI[BIILjava/lang/String;JZ)V

    • 解决方法 下载 hadoop.dll 放入windows的C:\Windows\System32
  2. 错误描述Name node is in safe mode. Name node处于安全模式

    • 解决方法:关闭安全模式
      关闭安全模式 hadoop dfsadmin -safemode leave
      进入安全模式 hadoop dfsadmin -safemode enter
  3. 通过 Java API 上传,与 Hadoop shell 上传的文件,副本系数不一样

    • 解释:Java API 上传,我们并没有指定副本系数,所以上传的副本数是hadoop默认的 3
      Hadoop shell 上传,我在 hdfs-site.xml 里设置过副本数,所以不会使用默认值
发表评论 / Comment

用心评论~