HDFS之使用Java客户端对文件的一些操作

在这里总结了一下使用java对HDFS上文件的操作,比如创建目录、上传下载文件、文件改名、删除……

首先对一些类名、变量名做出解释说明:

  1. FileSystem: 文件系统的抽象基类
    FileSystem的实现取决于fs.defaultFS的配置!

    有两种实现!
    LocalFileSystem: 本地文件系统 fs.defaultFS=file:///
    DistributedFileSystem: 分布式文件系统 fs.defaultFS=hdfs://xxx:9000

    声明用户身份:
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf, "atguigu");

  2. Configuration : 功能是读取配置文件中的参数

    Configuration在读取配置文件的参数时,根据文件名,从类路径按照顺序读取配置文件!
    先读取 xxx-default.xml,再读取xxx-site.xml

    Configuration类一加载,就会默认读取8个配置文件!
    将8个配置文件中所有属性,读取到一个Map集合中!

    也提供了set(name,value),来手动设置用户自定义的参数!

3. `FileStatus`
		代表一个文件的状态(文件的属性信息)
  1. offset和length
    offset是偏移量: 指块在文件中的起始位置
    length是长度,指块大小

     	比如:sts.zip 390M
     						length    offset
     	blk1:   0-128M      128M		0
     	blk2:    128M-256M  128M        128M
     	...
     	blk4:    384M-390M  6M          384M
    
    1. LocatedFileStatus
      LocatedFileStatus是FileStatus的子类,除了文件的属性,还有块的位置信息!

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

import java.io.IOException;
import java.net.URI;

public class TestHDFS {

    private FileSystem fs;
    Configuration conf = new Configuration();

    @Before
    public void init() throws Exception{
        //创建一个客户端对象
        fs = FileSystem.get(new URI("hdfs://hadoop101:9000"),conf,"sun");//URI不能为null,声明用户
    }

    //创建目录:hadoop fs -mkdir /xxx
    @Test
    public void testMkdir() throws Exception {
        //System.out.println(fs.getClass().getName());//输出当前使用的类名
        fs.mkdirs(new Path("/testHDFS"));//在HDFS的根目录下创建一个testHDFS目录
    }

    //上传文件:hadoop fs -put 本地文件 hdfs路径
    @Test
    public void testUpload() throws Exception{
        fs.copyFromLocalFile(false, new Path("e:/a.txt"), new Path("/"));
        //第一个参数代表上传后是否删除本地文件
    }


    //下载文件:hadoop fs -get hdfs文件 本地路径
    @Test
    public void testDownload() throws Exception{
        fs.copyToLocalFile(false,new Path("/a.txt"),new Path("e:/"),true);
        //最后一个参数代表下载文件的同时是否还下载.crc文件,即校验文件,true代表不下载!
    }

    //删除文件:hadoop fs -rm hdfs文件
    @Test
    public void testDelete() throws Exception{
        fs.delete(new Path("/a"), true);
        //recursive即是否递归删除
    }

    //重命名:hadoop fs -mv 源文件名 目标文件名
    @Test
    public void testRename() throws Exception{
        fs.rename(new Path("/a.txt"), new Path("/b.txt"));
    }

    //判断某个文件或目录是否存在
    @Test
    public void testIfPathExists()throws Exception{
        Path path = new Path("/a.txt");
        System.out.println(path);//true
    }

    //判断当前路径是目录还是文件
    @Test
    public void testIsFileOrDirectory() throws Exception{
        Path path = new Path("/a.txt");

        /*FileStatus fileStatus = fs.getFileStatus(path);
        System.out.println(fileStatus.isDirectory());//false
        System.out.println(fileStatus.isFile());//true*/

        FileStatus[] fileStatuses = fs.listStatus(path);//获取当前路径的所有文件及目录本身
        for (FileStatus status : fileStatuses) {
            Path filePath = status.getPath();
            //获取的文件名Path是完整的协议(即URI)+文件名,单独获得文件名需要filePath.getName()
            System.out.println(filePath.getName()+"是否是目录"+status.isDirectory());
            System.out.println(filePath.getName()+"是否是文件"+status.isFile());
        }


        //不建议使用此方法
        /*System.out.println(fs.isDirectory(path));//false
        System.out.println(fs.isFile(path));//true*/
    }

    //获取文件的块信息
    @Test
    public void testGetBlockInfo() throws Exception{
        Path path = new Path("/a.txt");

        RemoteIterator<LocatedFileStatus> status = fs.listLocatedStatus(path);

        while (status.hasNext()){
            LocatedFileStatus locatedFileStatus = status.next();

            //获取块的所属用户、所属组
            System.out.println(locatedFileStatus.getOwner());
            System.out.println(locatedFileStatus.getGroup());

            //获取块的位置信息
            BlockLocation[] blockLocations = locatedFileStatus.getBlockLocations();
            for (BlockLocation blockLocation : blockLocations) {
                System.out.println(blockLocation);//输出偏移量、长度、所有主机名
                System.out.println("-----------------------");
            }
        }

    }

    @After
    public void close() throws IOException {
        if(fs != null){
            fs.close();
        }
    }

}

原文地址:https://www.cnblogs.com/sunbr/p/13262325.html