HDFS读写数据

HDFS读写数据(流程+操作)

一.文件上传(I/O流)
1)客户端通过DistributedFileSystem模块向namenode请求上传文件
namenode检查
(1)目标文件是否已经存在
(2)父目录是否存在
(3)是否有文件上传权限等
(4)如果检查没问题,则会发送允许上传的响应

fs.create(new Path("/input/hadoop-2.7.3.tar.gz"))
(1)创建这个目录
(2)需要计算文件大小
(3)返回给DFSclient对象

2)namenode返回是否可以上传

3)客户端请求第一个block上传到那几个datanode服务器上,addBlock()

  1. namenode返回3个datanode节点,分别为dn1,dn2,dn3;

5)客户端通过FSDataOutStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,
然后dn2调用dn3,将这个通信管道建立完成。

6)dn1,dn2,dn3逐级应答客户端

7)客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存)
以packet为单位,dn1收到一个packet就会传给dn2,dn2就会传给dn3:dn1每传一个packet会放入一个应答队列等待应答

8)当一个block传输完成之后,客户端再次请求namenode上传第二个block的服务器(重复执行3-7步)

在这里插入图片描述
代码如下:

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;

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

public class HDFSio {
    public static void main(String[] args)throws IOException,URISyntaxException,InterruptedException{
       // readFileSeek1();
        //readFileSeek2();
        testput();
    }



    public static void testput() throws IOException {
        //1.配置文件信息
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS", "hdfs://nn-master:9000");
        //2.拿到文件系统对象
        FileSystem fileSystem = FileSystem.get(configuration);

        //3.找到目标地址的文件
        FileInputStream inputStream = new FileInputStream(
                new File("E:/hadoop-2.7.3.tar.gz"));

        //4.明确本机主机上文件位置:FSDataOutputSream
        FSDataOutputStream outputStream = fileSystem.create(new Path("/input/hadoop-2.7.3.tar.gz"));

        //4.利用IOUtils将目标文件复制到本机对应的目录下即可
        IOUtils.copyBytes(inputStream, outputStream, configuration);

        //5.关闭资源
        fileSystem.close();
    }

二.定位文件读取

1)客户端向namenode发送文件下载请求
2)namenode进行一系列检查
文件是否存在,是否有权限等
如果这一系列的检查没有问题,这个时候开始查询自己的元数据库
返回数据对应的块以及块的存储位置给客户端
例如:
hadoop.tar.gz
blk_9988789:hadoop01 hadoop02
blk_9988790:hadoop02 hadoop03
3)客户端拿到数据块的存储信息,开始进行第一个块的下载
4)第一块下载完成后,进行CRT校验(循环冗余校验码常用于外存储器和计算机同步通信的数据校验)
5)开始进行第二个块的下载,重复步骤四,进行文件追加
6)当所有数据块下载成功后,客户端向namenode反馈
代码实现:

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;

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

public class HDFSio {
    public static void main(String[] args)throws IOException,URISyntaxException,InterruptedException{
        readFileSeek1();
        readFileSeek2();
    }
    /**
     在获取hdfs上的指定文件的第1块数据块
 */


    public static  void readFileSeek1() throws IOException,InterruptedException, URISyntaxException {
        //1.获取文件系统
        Configuration configuration=new Configuration();
        FileSystem fs =FileSystem.get(new URI("hdfs://kepler:9000"),configuration,"root");
        //2.获取输入流
        FSDataInputStream fis=fs.open(new Path("/input/hadoop-2.7.3.tar.gz"));
        //3.创建输出流
        FileOutputStream fos=new FileOutputStream((new File("E:/hadoop-2.7.3.tar.gz.part1")));
        //4.流的拷贝
        byte[] buf=new byte[1024];
        //注意1024*128=128KB;
        //所以for循环了128KB次,每次循环从输入流中读取1024字节放buf中,总共读取的数据大小为128KB
        for(int i=0;i<1024*128;i++){
            fis.read(buf);
            fos.write(buf);
        }
        //5.关闭资源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);
    }
    /**
     在获取hdfs上的指定文件的第2块数据块
     */
    public static void readFileSeek2() throws IOException,InterruptedException,URISyntaxException{
        //1.获取文件系统
        Configuration configuration=new Configuration();
        FileSystem fs =FileSystem.get(new URI("hdfs://kepler:9000"),configuration,"root");
        //2.获取输入流
        FSDataInputStream fis=fs.open(new Path("/input/hadoop-2.7.3.tar.gz"));
        //3.定位数据位置
        fis.seek(1024*1024*128);
        //4.创建输出流
        FileOutputStream  fos=new FileOutputStream(new File("E:/hadoop-2.7.3.tar.gz.part2"));
        //5.流的对拷
        IOUtils.copyBytes(fis,fos,configuration);
        //6.关闭资源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);

    }
}

合并文件
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值