hadoop05-HDFS的api操作

这篇博客详细介绍了如何配置Eclipse以连接HDFS,包括环境变量设置、Hadoop插件安装、winutils配置,以及Java项目中依赖的添加。接着通过四个步骤展示了HDFS的API使用,包括连接测试、文件上传下载以及创建、删除文件的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境配置

eclipse配置hdfs的环境
  1. hadoop的插件hadoop-eclipse-plugin,放在eclipse的安装目录的plugins下
配置本地hadoop的环境
  1. 解压hadoop安装包
  2. 配置windows下hadoop的环境变量
    • 新建:HADOOP_HOME=hadoop的解压路径,我的是:HADOOP_HOME=C:\soft\hadoop-2.7.6
    • 在path下加上%HADOOP_HOME%bin;%HADOOP_HOME%sbin
  3. 配置windows下hadoop的相关插件
    • hadoop.dll放在C:\Windows\System32下
    • winutils.exe放在hadoop的安装目录的bin目录下
  4. 重启eclipse
  5. 配置eclipse可视化界面:
    • 启动eclipse;
    • windows下搜索hadoop,把hadoop的安装目录导过来,点击确定,应用
    • windows下showview选择other搜索mapreduce的location(配置之前保证hadoop集群是启动的)
    • 右键—new hadoop location —
    • location name = 可以任意指定
    • 左边指的是yarn的master,我的是:host:dadoop04,port:9001( 注意,需要提前在路径C:\Windows\System32\drivers\etc\hosts下配置好主机映射)
    • 右边是hdfs的主节点dfsmaster:dfsmaster的host:hadoop02,port:9000
    • username是登陆集群的用户名,我的是:hadoop
    • eclipse的可视化界面配置完成之后会出现一个DFS location

java项目中添加依赖:

  1. 项目下面建包:lib下的buildpath。
    • 好处:代码移动的时候比较方便,联通依赖包一起移动
    • 缺点:会造成工程很臃肿,jar包冲突
  2. maven添加依赖
    • 好处:代码比较轻便,自动解决jar包冲突的问题
    • 缺点:代码移动的时候,需要重新构建
  3. 创建本地用户依赖库

代码

1.测试hdfs的链接是否成功1

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

/**
 * 测试hdfs的链接是否成功
 * @author dai
 *
 */
public class testHdfs {
    public static void main(String[] args) throws IOException {
        //hdfs连接有两个重要的配置文件对象
        //对象01:配置文件对象  思考:作用?   配置文件从哪里来的?
        Configuration conf=new Configuration();
        //对象02:文件系统对象 FileSystem 是分布式文件系统的对象。  文件系统的句柄
        //在这里fs就是hdfs文件系统的抽象
        FileSystem fs=FileSystem.get(conf);
        System.out.println(fs);


        //文件上传
        /**
         * 参数1:本地的文件路径
         * 参数2:
         */
        // path对象是hdfs的内置路径对象,类似于windows下的file
        Path src=new Path("C:\\soft\\hadoop-2.7.6\\LICENSE.txt");
        //文件上传   这种方式传到哪里了=====还是本地。 默认情况下上传到工程所在的盘符下
        //上传成功之后生成两个文件:   testxxxx_tmp上传的原始文件,    还有一个testxxxx_tmp.crc文件,他是一个校验文件 
        Path dst=new Path("/testxxxx_tmp");
        fs.copyFromLocalFile(src, dst);

    }

}

2.测试hdfs的链接是否成功2

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

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;

/**
 * 测试hdfs的链接是否成功
 * @author dai
 *
 */
public class testHdfs2 {
    public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
        //System.setProperty("HADOOP_USER_NAME", "hadoop");
        /**
         * 文件上传成功了,提前设定集群中的副本为2个,  通过这种方式上传的文件的副本还是3个,为什么?
         *因为这里加载的配置文件,不是集群的,而代码中jar包中的。
         * 这里的conf对象默认加载的是hadoop-hdfs-2.7.6.jar包下的hdfs-default.xml文件
         * conf对象就是加载以下配置文件
         *      hdfs-default.xml
         *      core-default.xml
         *      yarn-default.xml
         *      mapred-default.xml
         *      hdfs-site.xml
         *      core-site.xml
         *      yarn-site.xml
         *      mapred-site.xml
         * conf对象加载配置文件的时候,加载次序:
         * jar包下加载》》》》src下加载》》》》 hdfs-default.xml   hdfs-site.xml>>>代码中的
         * 生效的顺序:
         *  代码中的》》》》src下的》》》》jar包中的
         * 
         */
        Configuration conf=new Configuration();
        //conf.set("dfs.replication", "5");
        //强制加载配置文件  加载指定的配置文件
        //conf.addResource("config/hdfs-site.xml");
        //conf.set("HADOOP_USER_NAME", "hadoop");

        /**
         * 在配置文件中,两个参数是k-v形式存在的
         *  <property>
         <name>fs.defaultFS</name>
         <value>hdfs://hadoop01:9000</value>
         </property>
         key:<name>fs.defaultFS</name>
         value:<value>hdfs://hadoop01:9000</value>
         设置分布式文件系统的入口
         */
        //conf.set("fs.defaultFS", "hdfs://hadoop01:9000");
        //FileSystem fs=FileSystem.get(conf);


        /**
         * 参数1:hdfs集群连接的主节点入口
         */
        FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");
        System.out.println(fs instanceof DistributedFileSystem);
        //当前的src是否可以是hdfs路径,汇报权限问题
        /**
         * 修改权限的集中方式:
         *  1)代码提交的时候进行设置参数
         *      右键》》》》run as>>>>  run configurations
         *      arguments>>>>>>>
         *      program arguments:代码中需要的参数   String[] args
         *      VM arguments: 代码运行中  jvm的参数
         *          jvm提交代码的时候的用户
         *          将用户名已添加上
         *      -DHADOOP_USER_NAME=hadoop
         * 2)在代码中添加:
         *  conf.set("HADOOP_USER_NAME", "hadoop");
         * 
         *  System.setProperty("HADOOP_USER_NAME", "hadoop");
         *  FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");
         * 3) 在windows的环境变量中
         *  HADOOP_USER_NAME=hadoop
         *
         *如果代码中和运行的时候都指定了用户名:
         *先加载运行指定的参数  在加载代码中,代码中的参数会覆盖掉运行指定的参数
         *最后生效的是代码中的
         */

        Path src=new Path("/cc/testcrc");
        Path dst=new Path("C:\\test_crc_04");
        /**
         * 文件上传成功之后会生成两个文件 :原始文件、CRC文件
         *      linux下查看一下:
         *          blk_1073741825    原始文件
                    blk_1073741825_1001.meta    元数据文件----crc文件   校验  存储的是原始文件的偏移量
                    校验数据的完整性    验证数据是否被修改了或损坏了   校验的时候与文件上传的时候的数据进行校验
         *          1)块的末尾追加不会影响校验
         *          2)块的中间追加,会影响校验,产生校验和错误
         *          结论:crc校验,从原始文件头---原始文件末尾  的校验,如果这部分内容不发生改变,不会影响校验    这部分内容发生改变的修啊吧则会报校验和错误 。
         * 
         * Exception in thread "main" org.apache.hadoop.fs.ChecksumException: Checksum error: /cc/testcrc at 0 exp: 1139544428 got: -1322830295
         * 文件块损坏的异常
         */
        //fs.copyFromLocalFile(src, dst);
        fs.copyToLocalFile(src, dst);
    }

}

3.用流的方式进行文件上传和下载

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

/**
 * 用流的方式进行文件上传和下载
 * @author dai
 *
 */
public class testHdfsStream {
    public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
        Configuration conf=new Configuration();
        FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");

        //文件上传
        /*//本地流,输入流
        FileInputStream in=new FileInputStream("C:\\testcrc.txt");
        //hdfs的输出流   create()   创建输出流
        FSDataOutputStream out = fs.create(new Path("/testcrc01"));
        //参数4:是否关闭流  true  关闭    false  不关闭
        IOUtils.copyBytes(in, out, 4096,true);*/

        //文件下载     hdfs(hdfs的输入流
        FSDataInputStream in01 = fs.open(new Path("/testcrc01"));
        in01.seek(5);
        //本地的输出流
        FileOutputStream out01=new FileOutputStream("C:\\testcrc03");
        IOUtils.copyBytes(in01, out01, 4096, true);
        fs.close();


    }

}

4.创建,删除,上传,下载文件等api操作

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;

public class testHdfsDemo01 {
    public static void main(String[] args) throws InterruptedException, URISyntaxException, IOException {
        Configuration conf=new Configuration();
        FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"),conf,"hadoop");
        //创建文件夹:级联创建,相当于hadoop fs  -mkdir -p
        /*boolean ifmk=fs.mkdirs(new Path("/xxxx/aa/bb/cc"));
        System.out.println(ifmk);*/
        //删除文件夹:文件   空目录  非空目录
        //fs.delete(new Path("/cc"));
        //参数1:删除的路径   参数2:是否递归删除  true  需要递归  false:不递归
        //fs.delete(new Path("/xxxx"), true);
        /*fs.copyFromLocalFile(src, dst);//上传
        fs.copyToLocalFile(src, dst);//下载
*/      

        //查看指定目录下的文件信息,相当于hadoop fs -ls /
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), false);
        //循环遍历输出
        while(listFiles.hasNext()){
            //System.out.println(listFiles.next());
            //LocatedFileStatus   描述hdfs上的文件或目录信息的对象
            LocatedFileStatus next = listFiles.next();
            System.out.println(next.getPath());
            System.out.println(next.getLen());//获取数据的真实长度
            System.out.println(next.getBlockSize());//获取块的大小

            /*//获取的是块存储信息
            *//**
             * BlockLocation   封装的是数据块的详细信息
             * 数据块的偏移量+数据块的存储位置(副本)
             * 0(数据块的其实偏移量),119978(块的实际大小),hadoop02,hadoop01(存储位置)
             * 
             */
            BlockLocation[] blockLocations = next.getBlockLocations();
            System.out.println("999999999999999999999999999999");
            for(BlockLocation bl:blockLocations){
                System.out.println(bl.getOffset());//获取块的起始偏移量
                System.out.println(bl.getLength());//获取块的实际的大小
                System.out.println(Arrays.toString(bl.getHosts()));//获取存储的主机   数组
            }

        }

        //获取状态信息  返回的是状态信息对象   FileStatus  封装的是一个路径的信息
        //这种方式只能返回文件或目录的状态信息   不能返回块信息   获取文件或目录的信息都可以
    /*  FileStatus[] listStatus = fs.listStatus(new Path("/"));

        for(FileStatus ff:listStatus){
            System.out.println("----------------------");
            System.out.println(ff.getPath());
            System.out.println(ff.getLen());
            System.out.println(ff.getReplication());
            System.out.println(ff.getBlockSize());
        }*/
        fs.close();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值