您现在的位置是:首页 >技术教程 >Hadoop框架-HDFS-客户端API操作网站首页技术教程
Hadoop框架-HDFS-客户端API操作
Hadoop框架-HDFS-客户端API操作学习笔记
一.客户端代码常用套路
客户端代码的常用套路分为以下三步:
1.获取一个客户端对象FileSystem
2.执行相关操作命令
3.关闭客户端对象
当然,在执行以上操作前,首先要确保Hadoop集群处于打开状态:
接下来便可以按照以上步骤进行API操作:
1.获取一个客户端对象FileSystem
当我们通过new的方式构造FileSystem对象时,出现了如下编译错误:
通过追溯源码我们发现FileSystem原来是一个抽象类,故而无法通过new的方式实例化对象:
因此我们转而通过get的方式来获取FileSystem对象:
这里get方法需要传入3个参数:
1.URI url: 连接的集群的namenode地址。由于我们把namenode节点放在了Hadoop102服务器上,并且HDFS在hadoop的内部通讯端口为:8020,使用了HDFS传输协议,故此参数设为:“hdfs://hadoop102:8020”
2.Configuration conf: 配置文件。这里直接通过new方式来获取所需的配置信息
3.String user: 用户id。如果不写的话,对文件将没有权限执行操作
接下来便可以编写代码了,为了方便后续使用,我们把获取客户端FileSystem对象的内容以一个init方法的形式封装起来,避免冗余的操作:
这里我们通过ctrl+alt+f命令把FileSystem对象升级为类中的一个全局变量(因为后续我们把关闭对象的操作也封装到了类中的另一方法内,关闭时需要调用该对象)
2.执行相关操作命令
此处可以直接跳到第二章节案例实操查看!!!
3.关闭客户端对象
同样,关闭资源的操作我们也封装到一个close方法内:
二、HDFS的API案例实操
1.创造目录 mkdirs
通过调用mkdirs方法即可创造一个目录:
注意这里我们为mkdirs方法传入的参数仅为1个Path对象,而Path对象内传入的即为要创造的目录路径。
代码如下:
@Test
public void testmkdir() throws URISyntaxException, IOException, InterruptedException {
fs.mkdirs(new Path("/fusir/qinqin"));
}
注:由于我们这里是Test测试方法,并使用了Junit注解规定了该方法会在Before方法(获取客户端FileSystem对象)之后执行,并在After方法(关闭客户端FileSystem对象)之前执行,所以只需要写需要执行的操作的代码即可。
运行之后,我们在Web端查看HDFS的namenode信息,可以看到新目录已创建:
注:查看Web端的网址:http://hadoop102:9870/
2.上传文件到HDFS客户端 CopyFromLocalFile
通过调用CopyFromLocalFile方法可从本地上传文件至Hadoop客户端
注:和Shell命令操作不同,客户端不能通过put方法上传文件
该方法共有4个参数,其中分别代表:
boolean delSrc: 是否删除源数据
boolean overwirte: 是否允许覆盖
Path src: 源数据路径
Path dst: 目的地路径
给定一个需求:从本地上传指定文件至客户端,同时删除本地文件,步骤如下:
首先在本地创建a.txt文件:
接着运行如下代码开始上传:
@Test
public void testPut() throws IOException {
fs.copyFromLocalFile(true,false,new Path("D:/timu/a.txt"),new Path("/fusir/qinqin"));
}
查看本地端发现a.txt已被删除:
查看客户端发现/fusir/qinqin目录下已有内容被上传:
3.下载文件到本地 CopyToLocalFile
通过调用CopyToLocalFile方法可把Hadoop客户端的文件下载至本地:
注:和Shell命令操作不同,客户端不能通过get方法下载文件
该方法同样也有4个参数,其中分别代表:
boolean delSrc: 是否删除源文件
Path src: 源文件路径
Path dst: 目的地路径
boolean useRawLocalFileSystem: 是否进行文件校验
给定一个需求:把客户端上的指定文件下载到本地,不删除客户端文件且不开启文件校验,代码如下:
@Test
public void testGet() throws IOException {
fs.copyToLocalFile(false,new Path("/MyJavaLearn/xixi.txt"),new Path("D:/timu/b.txt"),false);
}
查看本地端发现文件已下载:
查看客户端发现源文件没有被删除:
注:如果不进行校验,本地端会在下载源文件的同时生成一个crc文件;如果进行校验,则该crc文件不会产生。
4.删除文件 delete
通过调用delete方法可把Hadoop客户端的文件删除:
该方法有2个参数,其中分别代表:
Path path: 要删除的路径
boolean b: 是否递归删除
给定一个需求:删除客户端的fusir目录,要求递归删除其下所有文件与目录,代码如下:
@Test
public void testDelete() throws IOException {
fs.delete(new Path("/fusir"),true);
}
查看客户端发现源路径已消失:
给定另一需求:删除客户端MyJavaLearn目录下的指定文件,代码如下:
@Test
public void testDelete() throws IOException {
fs.delete(new Path("/MyJavaLearn/xixi.txt"),false);
}
查看客户端发现源文件已消失:
5.更名与移动 rename
通过调用rename方法可对Hadoop客户端的文件进行更名或移动:
该方法有2个参数,其中分别代表:
Path path: 源文件路径
Path path1: 目标文件路径
给定一个需求:把客户端的MyJavaLearn目录更名为mylearn:
更名前客户端:
运行代码:
@Test
public void testMv() throws IOException {
fs.rename(new Path("/MyJavaLearn"),new Path("/mylearn"));
}
更名后客户端:
给定另一需求:把客户端mylearn目录下的指定文件移动到主目录下:
移动前客户端:
运行如下代码:
@Test
public void testDelete() throws IOException {
fs.delete(new Path("/MyJavaLearn/xixi.txt"),false);
}
移动后客户端,可以看到文件已被转移到主目录下:
6.查看文件详情 listFiles
通过调用listFiles方法可在本地获取Hadoop客户端指定路径下的所有文件信息:
该方法有2个参数,其中分别代表:
Path f: 要查找的路径
boolean recursive: 是否递归查找
给定一个需求:查找客户端主目录下所有文件的信息详情,要求递归查找:
@Test
public void testListFiles() throws IOException {
//获取所有文件信息
RemoteIterator<LocatedFileStatus> listfiles = fs.listFiles(new Path("/"), true);
//遍历迭代器
while (listfiles.hasNext()) {
LocatedFileStatus next = listfiles.next();
System.out.println("========"+next.getPath()+"========");
//获取文件的访问权限
System.out.println(next.getPermission());
//获取文件属主
System.out.println(next.getOwner());
//获取文件属组
System.out.println(next.getGroup());
//获取文件长度
System.out.println(next.getLen());
//获取文件最近一次的修改时间
System.out.println(next.getModificationTime());
//获取文件的副本数
System.out.println(next.getReplication());
//获取文件的块大小
System.out.println(next.getBlockSize());
//获取文件名
System.out.println(next.getPath().getName());
//获取块信息
BlockLocation[] loc = next.getBlockLocations();
System.out.println(Arrays.toString(loc));
}
}
控制台的部分输出如下:
7.判断是文件/文件夹 listStatus
通过调用listStatus方法,可递归遍历客户端指定路径下的所有数据,
该方法的唯一参数Path path传入的是要判断的路径。
给定一个需求:判断客户端指定路径为文件还是文件夹:
@Test
public void testFile() throws IOException {
FileStatus[] listStatus = fs.listStatus(new Path("/mylearn"));
for (FileStatus status : listStatus) {
if (status.isFile()) {
System.out.println("文件:"+status.getPath().getName());
}else{
System.out.println("路径:"+status.getPath().getName());
}
}
}
控制台输出为:
@Test
@Test
public void testFile() throws IOException {
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus status : listStatus) {
//判断是否为文件
if (status.isFile()) {
System.out.println("文件:"+status.getPath().getName());
}//判断是否为目录
else if (status.isDirectory()) {
System.out.println("目录:"+status.getPath().getName());
}
}
}
}
控制台输出为: