在这里总结了一下使用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();
        }
    }
}