美文网首页我爱编程
hadoop学习之java操作hdfs

hadoop学习之java操作hdfs

作者: 你看见皮卡丘了吗 | 来源:发表于2018-04-08 16:03 被阅读67次

    之前已经在服务器上安装好了hadoop,下面纪录下用java操作hdfs和中间遇到的一些问题,使用的是分布式模式
    hdfs的介绍此处不赘述,可以自己去查阅相关资料进行了解

    一 本地配置hadoop环境变量

    此处默认已经具备jdk环境.
    将hadoop的压缩包解压到任意目录

    image.png

    在环境变量中配置HADOOP_HOME变量,值为hadoop所在的目录

    image.png

    打开cmd窗口,在其中输入hadoop version,出现如下界面即为环境变量配置成功

    image.png

    二 建立项目

    我使用的ide是idea,采用maven来管理项目.

    建立好maven项目之后,在pom文件下引入下述依赖.

    <!--hadoop 通用依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.9.0</version>
    </dependency>
    <!--hadoop hdfs依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.9.0</version>
    </dependency>
    <!--hadoop 客户端依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.9.0</version>
    </dependency>
    

    三 编写测试类及解决遇到的问题

    新建一个java文件,HdfsTest.java

    package com.example.hadoopdemo.hdfs;
    
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.fs.permission.FsPermission;
    import org.junit.Test;
    
    import java.io.IOException;
    
    public class HdfsTest {
        /**
        * 测试在hdfs文件系统中
        */
        @Test
        public void testHdfsCreateDir() throws IOException {
            //创建配置对象
            Configuration  conf = new Configuration();
            //设置文件系统
            conf.set("fs.defaultFS","hdfs://hadoop01:8020/");
            try {
                //获取文件系统
                FileSystem fileSystem = FileSystem.get(conf);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //新建path对象
            Path path = new Path("/data");
            //创建path对象所对应的目录
            fileSystem.mkdirs(path, FsPermission.getDefault());
        }
    }
    

    运行上面的测试方法,发现报了如下错误

    image.png

    这是因为在本地运行hadoop程序需要依赖一些依赖库和工具类,hadoop 2.9.0的依赖版本可以从下面百度云链接中下载

    链接:https://pan.baidu.com/s/1-hmTd7avPFpR8DK3GRgIBg 密码:tcnw

    下载完成后根据本机的位数选择对应的版本

    image.png

    将其中的所有文件都放到hadoop的bin目录下

    image.png

    此时在运行发现又报了错,错误信息如下

    TIM图片20180408150221.png

    这是因为我hadoop文件系统是用用户hadoop进行初始化的,而我本地windows的用户并不是hadoop,所以没有权限操作这个文件系统

    解决办法如下:
    一 是配置环境变量,HADOOP_USER_NAME,值为用户名,为hadoop

    image.png

    二 是在程序运行时加jvm参数 -DHADHOOP_USER_NAME=hadoop

    image.png

    三 是使用get的重载方法,直接提供用户名

    image.png

    此时再运行测试方法,可以看到运行成功

    这时我们去服务器上执行一下hadoop dfs -ls -R /

    image.png

    可以看到文件夹创建成功

    四 基本的hdfs操作

    下面贴出一些hdfs基本操作

    package com.example.hadoopdemo.hdfs;
    
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.*;
    import org.apache.hadoop.fs.permission.FsPermission;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class HdfsTest {
    
    
        /**
         * 静态初始化配置对象和文件系统对象
         */
        private static Configuration conf;
        static FileSystem fileSystem;
    
        static {
            conf = new Configuration();
            conf.set("fs.defaultFS", "hdfs://hadoop01:8020/", "aaaa");
            try {
                fileSystem = FileSystem.get(conf);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 创建目录
         *
         * @throws IOException
       */
        @Test
        public void testHdfsCreateDir() throws IOException {
            Path path = new Path("/data");
            fileSystem.mkdirs(path, FsPermission.getDefault());
        }
    
        /**
         * 创建文件
         *
         * @throws IOException
         */
        @Test
        public void testHdfsCreateFile() throws IOException {
            Path path = new Path("/data/hello.txt");
            FSDataOutputStream fos = fileSystem.create(path);
            fos.write("你好".getBytes());
            fos.close();
        }
    
        /**
         * 读取文件内容
         *
         * @throws IOException
         */
        @Test
        public void testHdfsReadFile() throws IOException {
            Path path = new Path("/data/hello.txt");
            FSDataInputStream fis = fileSystem.open(path);
            byte[] buffer = new byte[1024];
            fis.read(buffer);
            System.out.println(new String(buffer));
        }
    
    
        /**
         * 获取文件信息
         *
         * @throws IOException
         */
        @Test
        public void testHdfsGetFileStatus() throws IOException {
            Path path = new Path("/data/hello.txt");
            FileStatus fileStatus = fileSystem.getFileStatus(path);
            //fileStatus下有很多get方法获取文件的基础属性,下面列出几个
            //获取文件拥有者
            String owner = fileStatus.getOwner();
            //是否是目录
            boolean isDirectory = fileStatus.isDirectory();
            //是否是文件
            boolean isFile = fileStatus.isFile();
            //文件大小
            long len = fileStatus.getLen();
    
            System.out.println("文件拥有者:" + owner);
            System.out.println("是否是目录:" + isDirectory);
            System.out.println("是否是文件:" + isFile);
            System.out.println("文件大小:" + len);
        }
    
    
        /**
         * 通过反射获取文件的所有可获取的属性
         *
         * @throws IOException
         */
        @Test
        public void testHdfsReflectGetFileStatus() throws IOException, InvocationTargetException,IllegalAccessException {
            Path path = new Path("/data/hello.txt");
            FileStatus fileStatus = fileSystem.getFileStatus(path);
            Class<? extends FileStatus> fileStatusClass = fileStatus.getClass();
            Method[] methods = fileStatusClass.getMethods();
            //如果path不是symbolic的话 调用getSymbolic方法会报错,所以排除下
            for (Method method : methods) {
                String name = method.getName();
                if (name.startsWith("get") && !name.equals("getSymlink")) {
                    Object result = method.invoke(fileStatus);
                    System.out.println(name.substring(3) + ":" + result);
                } else if(name.startsWith("is")){
                    Object result = method.invoke(fileStatus);
                    System.out.println(name + ":" + result);
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:hadoop学习之java操作hdfs

        本文链接:https://www.haomeiwen.com/subject/tzhphftx.html