hadoop大数据(五)-HDFS概念和基本操作

一 HDFS简单介绍

1.1 HDFS产生背景

随着数据量越来越大,在一个操作系统管辖的范围内存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。

1.2 HDFS概念

HDFS**,它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的**,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。

HDFS的设计适合一次写入,多次读出的场景,且不支持文件的修改(也是可以修改的,但是不建议)。适合用来做数据分析,并不适合用来做网盘应用。

1.3 HDFS 优缺点

1.3.1 优点

1)高容错性

​ (1)数据自动保存多个副本。它通过增加副本的形式,提高容错性。

​ (2)某一个副本丢失以后,它可以自动恢复,这是由 HDFS 内部机制实现的,我们不必关心。

2)适合大数据处理

​ (1)数据规模:能够处理数据规模达到 GB、TB、甚至PB级别的数据。(因为他会切块存储,所以可以存储大文件-**参见HDFS**写数据流程

​ (2)文件规模:能够处理百万规模以上的文件数量,数量相当之大。

3)流式数据访问**(一点一点的处理数据,而不是一次性读取整个数据,这样会极大消耗内存)**

​ (1)一次写入,多次读取,不能修改,只能追加。

​ (2)它能保证数据的一致性。

4)可构建在廉价机器上

​ (1)它通过多副本机制,提高可靠性。

​ (2)它提供了容错和恢复机制。比如某一个副本丢失,可以通过其它副本来恢复。

1.3.2 缺点

1)不适合低延时数据访问

​ (1)比如毫秒级的来存储数据,这是不行的,它做不到。

​ (2)它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况下是不行的,比如毫秒级以内读取数据,这样它是很难做到的。

2)无法高效的对大量小文件进行存储(HDFS默认的最基本的存储单位是128M的数据块。)

​ (1)存储大量小文件;)的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。

​ (2)小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标。

3)并发写入、文件随机修改

​ (1)一个文件只能有一个写,不允许多个线程同时写

​ (2)仅支持数据 append(追加),不支持文件的随机修改。

img

1.4 HDFS架构

HDFS的架构图

​ 这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。下面我们分别介绍这四个组成部分。

1)Client:就是客户端。

​ (1)文件切分。文件上传 HDFS 的时候,Client 将文件切分成一个一个的Block,然后进行存储。

​ (2)与NameNode交互,获取文件的位置信息。

​ (3)与DataNode交互,读取或者写入数据。

​ (4)Client提供一些命令来管理HDFS,比如启动或者关闭HDFS。

​ (5)Client可以通过一些命令来访问HDFS。

2)NameNode:就是master,它是一个主管、管理者。

​ (1)管理HDFS的名称空间。

​ (2)管理数据块(Block);)映射信息

​ (3)配置副本策略;)

​ (4)处理客户端读写请求。

3) DataNode:就是Slave。NameNode下达命令,DataNode执行实际的操作。

​ (1)存储实际的数据块。

​ (2)执行数据块的读/写操作。

4) Secondary NameNode:并非NameNode的热备。当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务。

​ (1)辅助NameNode,分担其工作量。

​ (2)定期合并fsimage和fsedits;),并推送给NameNode。

​ (3)在紧急情况下,可辅助恢复NameNode。

1.5 HDFS 文件块大小

HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,老版本中是64M。

HDFS的块比磁盘的块大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个块组成的文件的时间取决于磁盘传输速率

如果寻址时间约为10ms,而传输速率为100MB/s,为了使寻址时间仅占传输时间的1%,我们要将块大小设置约为100MB。默认的块大小128MB。

块的大小:

10ms*100*100M/s = 100M

1560051715614

img

img

块大小取决于磁盘传输速率

二 HFDS命令行操作

操作HDFS的命令其实有三个:

​ Hadoop fs:使用面最广,可以操作任何文件系统。

​ hadoop dfs与hdfs dfs:只能操作HDFS文件系统相关(包括与Local FS间的操作),前者已经Deprecated,一般使用后者。

推荐使用:hadoop fs

1)基本语法

bin/hadoop fs 具体命令

2)参数大全

​ [kingge@hadoop102 hadoop-2.7.2]$ bin/hadoop fs

[-appendToFile ] [-cat [-ignoreCrc] …] [-checksum …] [-chgrp [-R] GROUP PATH…] [-chmod [-R] PATH…] [-chown [-R] [OWNER][:[GROUP]] PATH…] [-copyFromLocal [-f] [-p] ] [-copyToLocal [-p] [-ignoreCrc] [-crc] ] [-count [-q] …] [-cp [-f] [-p] ] [-createSnapshot []] [-deleteSnapshot ] [-df [-h] [ …]] [-du [-s] [-h] …] [-expunge] [-get [-p] [-ignoreCrc] [-crc] ] [-getfacl [-R] ] [-getmerge [-nl] ] [-help [cmd …]] [-ls [-d] [-h] [-R] [ …]] [-mkdir [-p] …] [-moveFromLocal ] [-moveToLocal ] [-mv ] [-put [-f] [-p] ] [-renameSnapshot ] [-rm [-f] [-r|-R] [-skipTrash] …] [-rmdir [–ignore-fail-on-non-empty]

…] [-setfacl [-R] [{-b|-k} {-m|-x } ]|[–set ]] [-setrep [-R] [-w] …] [-stat [format] …] [-tail [-f] ] [-test -[defsz] ] [-text [-ignoreCrc] …] [-touchz …] [-usage [cmd …]]

[-appendToFile <localsrc> ... <dst>]
[-cat [-ignoreCrc] <src> ...]
[-checksum <src> ...]
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-copyFromLocal [-f] [-p] <localsrc> ... <dst>]
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-count [-q] <path> ...]
[-cp [-f] [-p] <src> ... <dst>]
[-createSnapshot <snapshotDir> [<snapshotName>]]
[-deleteSnapshot <snapshotDir> <snapshotName>]
[-df [-h] [<path> ...]]
[-du [-s] [-h] <path> ...]
[-expunge]
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-getfacl [-R] <path>]
[-getmerge [-nl] <src> <localdst>]
[-help [cmd ...]]
[-ls [-d] [-h] [-R] [<path> ...]]
[-mkdir [-p] <path> ...]
[-moveFromLocal <localsrc> ... <dst>]
[-moveToLocal <src> <localdst>]
[-mv <src> ... <dst>]
[-put [-f] [-p] <localsrc> ... <dst>]
[-renameSnapshot <snapshotDir> <oldName> <newName>]
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
[-setrep [-R] [-w] <rep> <path> ...]
[-stat [format] <path> ...]
[-tail [-f] <file>]
[-test -[defsz] <path>]
[-text [-ignoreCrc] <src> ...]
[-touchz <path> ...]
[-usage [cmd ...]]

3)常用命令

(0)启动Hadoop集群(方便后续的测试)

​ [kingge@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh

[kingge@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

(1)-help:输出这个命令参数

​ [kingge@hadoop102 hadoop-2.7.2]$ bin/hdfs dfs -help rm

​ (2)-ls: 显示目录信息

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -ls /

(3)-mkdir:在hdfs上创建目录

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir -p /user/kingge/test

(4)-moveFromLocal从本地剪切粘贴到hdfs

[kingge@hadoop102 hadoop-2.7.2]$ touch jinlian.txt

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -moveFromLocal ./jinlian.txt /user/kingge/test

(5)–appendToFile :追加一个文件到已经存在的文件末尾

[kingge@hadoop102 hadoop-2.7.2]$ touch ximen.txt

[kingge@hadoop102 hadoop-2.7.2]$ vi ximen.txt

输入

wo ai jinlian

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -appendToFile ximen.txt /user/kingge/test/jinlian.txt

(6)-cat :显示文件内容

(7)-tail:显示一个文件的末尾

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -tail /user/kingge/test/jinlian.txt

(8)-chgrp 、-chmod、-chown:linux文件系统中的用法一样,修改文件所属权限

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -chmod 666 /hello.txt

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -chown someuser:somegrp /hello.txt

(9)-copyFromLocal:从本地文件系统中拷贝文件到hdfs路径去

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -copyFromLocal README.txt /user/kingge/test

(10)-copyToLocal:从hdfs拷贝到本地

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -copyToLocal /user/kingge/test/jinlian.txt ./jinlian.txt

(11)-cp :从hdfs的一个路径拷贝到hdfs的另一个路径

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -cp /user/kingge/test/jinlian.txt /jinlian2.txt

(12)-mv:在hdfs目录中移动文件

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -mv /jinlian2.txt /user/kingge/test/

(13)-get:等同于copyToLocal,就是从hdfs下载文件到本地

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -get /user/kingge/test/jinlian2.txt ./

(14)-getmerge :合并下载多个文件,比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,…

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -getmerge /user/kingge/test/* ./zaiyiqi.txt

(15)-put:等同于copyFromLocal

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -put ./zaiyiqi.txt /user/kingge/test/

(16)-rm:删除文件或文件夹

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -rm /user/kingge/test/jinlian2.txt

(17)-rmdir:删除空目录

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir /test

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -rmdir /test

(18)-df :统计文件系统的可用空间信息

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -df -h /

(19)-du统计文件夹的大小信息

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -du -s -h /user/kingge/test

2.7 K /user/kingge/test ###查看文件夹下文件总大小

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -du -h /user/kingge/test

1.3 K /user/kingge/test/README.txt

15 /user/kingge/test/jinlian.txt

1.4 K /user/kingge/test/zaiyiqi.txt

##查看文件夹下各个文件大小

(20)-setrep:设置hdfs中文件的副本数量

[kingge@hadoop102 hadoop-2.7.2]$ hadoop fs -setrep 2 /user/kingge/test/jinlian.txt

img

这里设置的副本数只是记录在namenode的元数据中,是否真的会有这么多副本,还得看datanode的数量。因为目前只有3台设备,最多也就3个副本,只有节点数的增加到10台时,副本数才能达到10。

三 HDFS客户端操作-eclipse

3.1 Eclipse环境准备

注意:以下操作,是在hadoop集群中中进行的,也就是说,需要先启动linux的hadoop集群

3.1.1 jar包准备

1)解压hadoop-2.7.2.tar.gz到非中文目录

2)进入share文件夹,查找所有jar包,并把jar包拷贝到_lib文件夹下

3)在全部jar包中查找sources.jar,并剪切到_source文件夹。

4)在全部jar包中查找tests.jar,并剪切到_test文件夹。

3.1.2 Eclipse准备

1)配置HADOOP_HOME环境变量

2)采用Hadoop编译后的bin 、lib两个文件夹(如果不生效,重新启动eclipse)

3)创建第一个java工程

4)导入 编译后目录的jar包(可以在文章下方回复我,我私信给你们

public class HdfsClientDemo1 { public static void main(String[] args) throws Exception { // 1 获取文件系统 Configuration configuration = new Configuration(); // 配置在集群上运行 configuration.set(“fs.defaultFS”, “hdfs://hadoop102:9000”); FileSystem fileSystem = FileSystem.get(configuration); // 直接配置访问集群的路径和访问集群的用户名称 // FileSystem fileSystem = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 2 把本地文件上传到文件系统中 fileSystem.copyFromLocalFile(new Path(“f:/hello.txt”), new Path(“/hello1.copy.txt”)); // 3 关闭资源 fileSystem.close(); System.out.println(“over”); } }

public class HdfsClientDemo1 {
public static void main(String[] args) throws Exception {
// 1 获取文件系统
Configuration configuration = new Configuration();
// 配置在集群上运行 - 如果不配置,默认使用的是本地的hadoop运行环境。
configuration.set("fs.defaultFS", "hdfs://hadoop102:9000");
FileSystem fileSystem = FileSystem.get(configuration);
// 直接配置访问集群的路径和访问集群的用户名称
// FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 2 把本地文件上传到文件系统中
fileSystem.copyFromLocalFile(new Path("f:/hello.txt"), new Path("/hello1.copy.txt"));
// 3 关闭资源
fileSystem.close();
System.out.println("over");
}
}

4)执行程序

运行时需要配置用户名称

img

客户端去操作hdfs时,是有一个用户身份的。默认情况下,hdfs客户端api会从jvm中获取一个参数来作为自己的用户身份:-DHADOOP_USER_NAME=kingge,kingge为用户名称。

3.2 通过API操作HDFS

3.2.1 HDFS获取文件系统

1)详细代码

​ @Test public void initHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); // 2 获取文件系统 FileSystem fs = FileSystem.get(configuration); // 3 打印文件系统 System.out.println(fs.toString()); }

@Test
public void initHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
// 2 获取文件系统
FileSystem fs = FileSystem.get(configuration);
// 3 打印文件系统
System.out.println(fs.toString());
}

3.2.2 HDFS文件上传

@Test
public void putFileToHDFS() throws Exception{
// 1 创建配置信息对象
// new Configuration();的时候,它就会去加载jar包中的hdfs-default.xml
// 然后再加载classpath下的hdfs-site.xml
Configuration configuration = new Configuration();
// 2 设置参数
// 参数优先级: 1、客户端代码中设置的值 2、classpath下的用户自定义配置文件 3、然后是服务器的默认配置
configuration.set("dfs.replication", "2");
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 3 创建要上传文件所在的本地路径
Path src = new Path("e:/hello.txt");
// 4 创建要上传到hdfs的目标路径
Path dst = new Path("hdfs://hadoop102:9000/user/kingge/hello.txt");
// 5 拷贝文件
fs.copyFromLocalFile(src, dst);
fs.close();
}

​ @Test public void putFileToHDFS() throws Exception{ // 1 创建配置信息对象 // new Configuration();的时候,它就会去加载jar包中的hdfs-default.xml // 然后再加载classpath下的hdfs-site.xml Configuration configuration = new Configuration(); // 2 设置参数 // 参数优先级: 1、客户端代码中设置的值 2、classpath下的用户自定义配置文件 3、然后是服务器的默认配置 configuration.set(“dfs.replication”, “2”); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 3 创建要上传文件所在的本地路径 Path src = new Path(“e:/hello.txt”); // 4 创建要上传到hdfs的目标路径 Path dst = new Path(“hdfs://hadoop102:9000/user/atguigu/hello.txt”); // 5 拷贝文件 fs.copyFromLocalFile(src, dst); fs.close(); }

2)将core-site.xml拷贝到项目的根目录下

<?xml version=”1.0” encoding=”UTF-8”?> <?xml-stylesheet type=”text/xsl” href=”configuration.xsl”?> fs.defaultFS hdfs://hadoop102:9000

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 指定HDFS中NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:9000</value>
</property>
</configuration>

3)将hdfs-site.xml拷贝到项目的根目录下

<?xml version=”1.0” encoding=”UTF-8”?> <?xml-stylesheet type=”text/xsl” href=”configuration.xsl”?> dfs.replication 1

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>

4)测试参数优先级

参数优先级: 1**、客户端代码中设置的值 2、classpath下的用户自定义配置文件 3**、然后是服务器的默认配置

3.2.3 HDFS文件下载

@Test public void getFileFromHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // fs.copyToLocalFile(new Path(“hdfs://hadoop102:9000/user/atguigu/hello.txt”), new Path(“d:/hello.txt”)); // boolean delSrc 指是否将原文件删除 // Path src 指要下载的文件路径 // Path dst 指将文件下载到的路径 // boolean useRawLocalFileSystem 是否开启文件效验 // 2 下载文件 fs.copyToLocalFile(false, new Path(“hdfs://hadoop102:9000/user/atguigu/hello.txt”), new Path(“e:/hellocopy.txt”), true); fs.close(); }

@Test
public void getFileFromHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// fs.copyToLocalFile(new Path("hdfs://hadoop102:9000/user/kingge/hello.txt"), new Path("d:/hello.txt"));
// boolean delSrc 指是否将原文件删除
// Path src 指要下载的文件路径
// Path dst 指将文件下载到的路径
// boolean useRawLocalFileSystem 是否开启文件效验
// 2 下载文件
fs.copyToLocalFile(false, new Path("hdfs://hadoop102:9000/user/kingge/hello.txt"), new Path("e:/hellocopy.txt"), true);
fs.close();
}

3.2.4 HDFS目录创建

​ @Test public void mkdirAtHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); //2 创建目录 fs.mkdirs(new Path(“hdfs://hadoop102:9000/user/atguigu/output”)); }

@Test
public void mkdirAtHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
//2 创建目录
fs.mkdirs(new Path("hdfs://hadoop102:9000/user/kingge/output"));
}

3.2.5 HDFS文件夹删除

@Test
public void deleteAtHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
//2 删除文件夹 ,如果是非空文件夹,参数2是否递归删除,true递归
fs.delete(new Path("hdfs://hadoop102:9000/user/kingge/output"), true);
}

​ @Test public void deleteAtHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); //2 删除文件夹 ,如果是非空文件夹,参数2是否递归删除,true递归 fs.delete(new Path(“hdfs://hadoop102:9000/user/atguigu/output”), true); }

3.2.6 HDFS文件名更改

​ @Test public void renameAtHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); //2 重命名文件或文件夹 fs.rename(new Path(“hdfs://hadoop102:9000/user/atguigu/hello.txt”), new Path(“hdfs://hadoop102:9000/user/atguigu/hellonihao.txt”)); }

@Test
public void renameAtHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
//2 重命名文件或文件夹
fs.rename(new Path("hdfs://hadoop102:9000/user/kingge/hello.txt"), new Path("hdfs://hadoop102:9000/user/kingge/hellonihao.txt"));
}

3.2.7 HDFS文件详情查看

查看文件名称、权限、长度、块信息-不是文件夹,是文件

@Test public void readListFiles() throws Exception { // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 思考:为什么返回迭代器,而不是List之类的容器 RemoteIterator listFiles = fs.listFiles(new Path(“/“), true); while (listFiles.hasNext()) { LocatedFileStatus fileStatus = listFiles.next(); System.out.println(fileStatus.getPath().getName()); System.out.println(fileStatus.getBlockSize()); System.out.println(fileStatus.getPermission()); System.out.println(fileStatus.getLen()); BlockLocation[] blockLocations = fileStatus.getBlockLocations(); for (BlockLocation bl : blockLocations) { System.out.println(“block-offset:” + bl.getOffset()); String[] hosts = bl.getHosts(); for (String host : hosts) { System.out.println(host); } } System.out.println(“————–李冰冰的分割线————–”); } }

@Test
public void readListFiles() throws Exception {
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 思考:为什么返回迭代器,而不是List之类的容器
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while (listFiles.hasNext()) {
LocatedFileStatus fileStatus = listFiles.next();
System.out.println(fileStatus.getPath().getName());
System.out.println(fileStatus.getBlockSize());
System.out.println(fileStatus.getPermission());
System.out.println(fileStatus.getLen());
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
for (BlockLocation bl : blockLocations) {
System.out.println("block-offset:" + bl.getOffset());
String[] hosts = bl.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("--------------李冰冰的分割线--------------");
}
}

3.2.8 HDFS文件和文件夹判断

不支持递归,只能查询当前某个目录下的文件或者或者文件夹,然后判断

@Test
public void findAtHDFS() throws Exception, IllegalArgumentException, IOException{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 2 获取查询路径下的文件状态信息
FileStatus[] listStatus = fs.listStatus(new Path("/"));
// 3 遍历所有文件状态
for (FileStatus status : listStatus) {
if (status.isFile()) {
System.out.println("f--" + status.getPath().getName());
} else {
System.out.println("d--" + status.getPath().getName());
}
}
}

@Test public void findAtHDFS() throws Exception, IllegalArgumentException, IOException{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 2 获取查询路径下的文件状态信息 FileStatus[] listStatus = fs.listStatus(new Path(“/“)); // 3 遍历所有文件状态 for (FileStatus status : listStatus) { if (status.isFile()) { System.out.println(“f–” + status.getPath().getName()); } else { System.out.println(“d–” + status.getPath().getName()); } } }

3.3 通过IO流操作HDFS

3.3.1 HDFS文件上传

​ @Test public void putFileToHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 2 创建输入流 FileInputStream inStream = new FileInputStream(new File(“e:/hello.txt”)); // 3 获取输出路径 String putFileName = “hdfs://hadoop102:9000/user/atguigu/hello1.txt”; Path writePath = new Path(putFileName); // 4 创建输出流 FSDataOutputStream outStream = fs.create(writePath); // 5 流对接 try{ IOUtils.copyBytes(inStream, outStream, 4096, false); }catch(Exception e){ e.printStackTrace(); }finally{ IOUtils.closeStream(inStream); IOUtils.closeStream(outStream); } }

@Test
public void putFileToHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 2 创建输入流
FileInputStream inStream = new FileInputStream(new File("e:/hello.txt"));
// 3 获取输出路径
String putFileName = "hdfs://hadoop102:9000/user/kingge/hello1.txt";
Path writePath = new Path(putFileName);
// 4 创建输出流
FSDataOutputStream outStream = fs.create(writePath);
// 5 流对接
try{
IOUtils.copyBytes(inStream, outStream, 4096, false);
}catch(Exception e){
e.printStackTrace();
}finally{
IOUtils.closeStream(inStream);
IOUtils.closeStream(outStream);
}
}

3.3.2 HDFS文件下载

​ @Test public void getFileToHDFS() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”),configuration, “atguigu”); // 2 获取读取文件路径 String filename = “hdfs://hadoop102:9000/user/atguigu/hello1.txt”; // 3 创建读取path Path readPath = new Path(filename); // 4 创建输入流 FSDataInputStream inStream = fs.open(readPath); // 5 流对接输出到控制台 try{ IOUtils.copyBytes(inStream, System.out, 4096, false); }catch(Exception e){ e.printStackTrace(); }finally{ IOUtils.closeStream(inStream); } }

@Test
public void getFileToHDFS() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"),configuration, "kingge");
// 2 获取读取文件路径
String filename = "hdfs://hadoop102:9000/user/kingge/hello1.txt";
// 3 创建读取path
Path readPath = new Path(filename);
// 4 创建输入流
FSDataInputStream inStream = fs.open(readPath);
// 5 流对接输出到控制台
try{
IOUtils.copyBytes(inStream, System.out, 4096, false);
}catch(Exception e){
e.printStackTrace();
}finally{
IOUtils.closeStream(inStream);
}
}

3.3.3 定位文件读取

1)下载第一块

@Test // 定位下载第一块内容 public void readFileSeek1() throws Exception { // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”), configuration, “atguigu”); // 2 获取输入流路径 Path path = new Path(“hdfs://hadoop102:9000/user/atguigu/tmp/hadoop-2.7.2.tar.gz”); // 3 打开输入流 FSDataInputStream fis = fs.open(path); // 4 创建输出流 FileOutputStream fos = new FileOutputStream(“e:/hadoop-2.7.2.tar.gz.part1”); // 5 流对接 byte[] buf = new byte[1024]; for (int i = 0; i < 128 1024; i++) { fis.read(buf); fos.write(buf); } // 6 关闭流 IOUtils.closeStream(fis); IOUtils.closeStream*(fos); }

@Test
// 定位下载第一块内容
public void readFileSeek1() throws Exception {
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "kingge");
// 2 获取输入流路径
Path path = new Path("hdfs://hadoop102:9000/user/kingge/tmp/hadoop-2.7.2.tar.gz");
// 3 打开输入流
FSDataInputStream fis = fs.open(path);
// 4 创建输出流
FileOutputStream fos = new FileOutputStream("e:/hadoop-2.7.2.tar.gz.part1");
// 5 流对接
byte[] buf = new byte[1024];
for (int i = 0; i < 128 * 1024; i++) {
fis.read(buf);
fos.write(buf);
}
// 6 关闭流
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}

2)下载第二块

​ @Test // 定位下载第二块内容 public void readFileSeek2() throws Exception{ // 1 创建配置信息对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop102:9000”), configuration, “atguigu”); // 2 获取输入流路径 Path path = new Path(“hdfs://hadoop102:9000/user/atguigu/tmp/hadoop-2.7.2.tar.gz”); // 3 打开输入流 FSDataInputStream fis = fs.open(path); // 4 创建输出流 FileOutputStream fos = new FileOutputStream(“e:/hadoop-2.7.2.tar.gz.part2”); // 5 定位偏移量(第二块的首位) fis.seek(1024 1024 128); // 6 流对接 IOUtils.copyBytes(fis, fos, 1024); // 7 关闭流 IOUtils.closeStream(fis); IOUtils.closeStream(fos); }

@Test
// 定位下载第二块内容
public void readFileSeek2() throws Exception{
// 1 创建配置信息对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "kingge");
// 2 获取输入流路径
Path path = new Path("hdfs://hadoop102:9000/user/kingge/tmp/hadoop-2.7.2.tar.gz");
// 3 打开输入流
FSDataInputStream fis = fs.open(path);
// 4 创建输出流
FileOutputStream fos = new FileOutputStream("e:/hadoop-2.7.2.tar.gz.part2");
// 5 定位偏移量(第二块的首位)
fis.seek(1024 * 1024 * 128);
// 6 流对接
IOUtils.copyBytes(fis, fos, 1024);
// 7 关闭流
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}

3)合并文件

在window命令窗口中执行

type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1

解压,发现,就是我们上传的压缩文件。

如果你感觉文章对你又些许感悟,你可以支持我!!
-------------本文结束感谢您的阅读-------------