一 、配置Windows下的Hadoop环境

hadoop的api路径 hadoop java api_hadoop


导入依赖与插件

<dependencies>
    <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-common</artifactId>
                <version>2.7.5</version>
    </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-client</artifactId>
                <version>2.7.5</version>
    </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <!--   <verbal>true</verbal>-->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <minimizeJar>true</minimizeJar>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

二、Java的api操作

1.涉及的主要类

Configuration
该类的对象封装了客户端或者服务器的配置
FileSystem
该类的对象是一个文件系统对象,用于操作文件,通过FileSystem的静态方法get获取对象

1.1获取FileSystem的几种方式

第一种
@Test
    public void getFileSystem1() throws IOException {
        Configuration configuration = new Configuration();
        //设置配置信息,第一个参数是固定的,第二个表示分布式文件系统
        configuration.set("fs.defaultFS","hdfs://node01:9000/");
        FileSystem fileSystem = FileSystem.get(configuration);
        System.out.println(fileSystem);
    }
第二种

使用套接字地址和默认配置获取

@Test
    public void getFileSystem2() throws URISyntaxException, IOException {
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
        System.out.println(fileSystem);
    }
第三种
@Test
    public void getFileSystem3() throws IOException {
        Configuration configuration = new Configuration();
        //设置配置信息,第一个参数是固定的,第二个表示分布式文件系统
        configuration.set("fs.defaultFS","hdfs://node01:9000/");
        FileSystem fileSystem = FileSystem.newInstance(configuration);
        System.out.println(fileSystem);
    }
第四种
@Test
    public void getFileSystem4() throws IOException, URISyntaxException {
        FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://node01:8020"), new Configuration());
        System.out.println(fileSystem);
    }

2.遍历HDFS所有文件

@Test
    public void fileList() throws URISyntaxException, IOException {
        FileSystem fileSystem =
                FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
        //获取根目录下所有目录的所有文件
        //第一个参数代表所要获取的目前,第二个决定是否递归获取目录里的子目录
        //得到迭代器
        RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
        while (iterator.hasNext())
        {
            LocatedFileStatus fileStatus = iterator.next();
            //通过fileStatus获取文件相关信息
            //获取文件的绝对路径和文件名
            System.out.println(fileStatus.getPath()+":"+fileStatus.getPath().getName());
            //获取文件的block信息
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(blockLocations.length);
        }
    }

3.创建目录

默认是可以递归创建目录和文件的

@Test
    public void mkdir() throws URISyntaxException, IOException, InterruptedException {
        //要注意权限
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration(),"root");
        //创建目录
        fileSystem.mkdirs(new Path("/test/testdir"));
        //创建文件
        fileSystem.create(new Path("/test/testdir/test.txt"));
        fileSystem.close();
    }

4.文件下载/上传

//下载文件
    @Test
    public void download() throws URISyntaxException, IOException {
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
        //获取HDFS输入流
        FSDataInputStream inputStream = fileSystem.open(new Path("/test/a.txt"));
        //创建一个输入流
        FileOutputStream outputStream = new FileOutputStream("a.txt");
        IOUtils.copy(inputStream,outputStream);
        //关闭流
        IOUtils.closeQuietly(inputStream);
        IOUtils.closeQuietly(outputStream);
    }

也可以调用copyTolocalFile

//下载文件
    @Test
    public void download2() throws URISyntaxException, IOException {
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
        fileSystem.copyToLocalFile(new Path("/test/a.txt"),new Path("a.txt"));

    }

上传文件就是调用copyFromLocalFile

@Test
    public void put() throws URISyntaxException, IOException {
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
        //本地路径和目标路径
        fileSystem.copyFromLocalFile(new Path("a.txt"),new Path("/test/a.txt"));
    }

5.小文件合并

由于 Hadoop 擅长存储大文件,因为大文件的元数据信息比较少,如果 Hadoop 集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理

我们可以直接使用shell命令来下载合并文件

hdfs dfs -getmerge /config/*.xml ./hello.xml

一般情况下,我们都是将文件合并后再上传HDFS

//合并文件并上传
    @Test
    public void mergeput() throws URISyntaxException, IOException, InterruptedException {
        FileSystem fileSystem =
                FileSystem.get(new URI("hdfs://node01:9000"), new Configuration(),"root");
        //在HDFS创建文件,获得输出流
        FSDataOutputStream outputStream = fileSystem.create(new Path("/mergefileandput.txt"));
        //获取本地文件系统
        LocalFileSystem localFileSystem = FileSystem.getLocal(new Configuration());
        //获取所需要上传的本地文件
        FileStatus[] fileStatuses = localFileSystem.listStatus(new Path("test"));
        //遍历,合并上传
        for (FileStatus fileStatus : fileStatuses) {
            //获取每个文件的输入流
            FSDataInputStream inputStream = localFileSystem.open(fileStatus.getPath());
            IOUtils.copy(inputStream,outputStream);
            IOUtils.closeQuietly(inputStream);
        }
        IOUtils.closeQuietly(outputStream);
        localFileSystem.close();
    }