【2-4】用Java接口操作HDFS

6 篇文章 0 订阅

我们使用shell只进行一些简单的操作,还是用Java接口比较多。因此我们要使用Java接口的方式来操作HDFS

我们new一个project 叫hadoop0106,然后再创建一个文件夹(new一个folder)叫lib,把jar包导入进去


在hadoop2.2.0/share/hadoop/common 里面的三个jar包 Ctrl+c

在hadoop2.2.0/share/hadoop/common/lib下边的一大堆jar包 复制过来。

在hadoop2.2.0/share/hadoop/hdfs 里面的三个jar包

之后,我们点击jar包,之后点右键——构建路径,把这些jar包变成一个一个“奶瓶”,之后在Java构建路径中,它们变成了一个一个的小奶瓶


然后,我们创建一个包叫cn.itcast.hadoop.hdfs,在包里创建一个类,叫HDFSDemo,如图


我无需了解哪些底层信息,而是它给我一个工具类,只要我使用这些工具类,就能把这些细节隐藏起来。


HDFS里有一个工具类叫:FileSystem  来自org.apache.包

在讲课的人里面,他一输入FileSystem,就能出来这个包,还能自动import这个包,我一出来就是报错


原因:他用了快捷键Alt+/这个键 之后只要双击那个org.apache.hadoop.fs那个,就可以自动import那个包了。

上次就卡在这里了,现在,继续开工!


我发现FileSystem是一个抽象类(abstract),不能用【至于怎么发现是抽象类的,关联了源码,这个我还没看懂】PS解释:导入源码之后,点击Ctrl+你想选的类,就能看到这个类的源码,源码里面写的是abstract,说明这个是个抽象类。2016.1.22

之后用FileSystemget方法,得到了一个具体的实现类


得到了实现类,就可以“玩” 了,可以来一个下载,我已经得到一个实现类“fs”了,那么先打开

打开是fs.open,我现在要打开一个路径,把它读进来。 我要从HDFS下载,需要先把HDFS文件读入到内存,然后再把数据写入到本地文件系统,因此,我们应该打开一个HDFS上的文件,

我们可以简写“/jdk1.7”  这个文件在HDFS上,


把这个文件先读进来。读进来之后,我还要new一个outputstream,写入文件系统


后面的地址是自己在Windows上的地址 c://jkd1.7


我们使用IOUtils.copyBytes() 将in里的内容拷贝到out,buffersize=4096,拷贝完成之后穿true就关闭

完整代码如下:

package cn.itcast.hadoop.hdfs;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

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

public class HDFSDemo1 {

	public static void main(String[] args) throws Exception{
		// TODO 自动生成的方法存根
			FileSystem fs = FileSystem.get(new URI("hdfs://itcast01:9000"),new Configuration());
			InputStream in =  fs.open(new Path("/in.log"));
			OutputStream out = new FileOutputStream("c://windowsin.log");
			IOUtils.copyBytes(in, out, 4096, true);
			
	}

}

代码的作用,是在Windows系统的C盘下,把hdfs上的in.log编程了windowsin.log。

值得注意的是,前面的import至关重要,导入时候用Alt+/ 但是容易导错,导错的话是无法解析出结果的。

当运行成功时,控制台给出的这样的结果


然后在window系统中便能看到我们从网上“下载”的数据了。





下载之后,接下来练习一下上传

上传我要用junit试一下【org.junit.before】

上传是将本地的文件上传到HDFS上

方法:首先,读取本地文件系统的文件,读取是input,之后在HDFS上创建一个文件,读取是in,创建是out,所以,我们将in里的内容创建到out里面去就可以了。

FileInputStream的父类:InputStream in = new FileInputStream("c://");

【AK: 每次新加了一个东西之后,都显示报错,之后让我“添加抛出声明”?这是what】


添加的时候遇到一个问题,在我 InputStream in =new FileInputStream("c://123.txt");//把本地文件系统作为inputstream读进来了

时,右键testUpload时候,运行失败,显示的是FileInputStream系统找不到指定文件。这时候,是因为我当时上传的windowsin是log文件,需要加上尾缀。


先定义一个初始化方法public void init()【因为都要用到初始化方法,因此单独拎出来】

代码如下:

FileSystem fs = null;
	@Before
	public void init() throws IOException,URISyntaxException, InterruptedException{
<span style="white-space:pre">		</span>//首先创建FileSystem的实现类(它是一个工具类)
		fs = FileSystem.get(new URI("hdfs://itcast01:9000"),new Configuration(),"root");//伪装成root,为了有权限
	}
	
	@Test
	public void testUpload() throws Exception{
		//首先要读取一个本地文件系统的文件,返回输入流
		InputStream in =new FileInputStream("c://123.txt");//把本地文件系统作为inputstream读进来了
<span style="white-space:pre">		</span>//在HDFS上创建一个文件,返回输出流
		OutputStream out = fs.create(new Path("/test.jar"));//这时候不能new了,要指向HDFS文件了
		//输入—>输出
<span style="white-space:pre">		</span>IOUtils.copyBytes(in, out, 4096, true);
	}
	

这种方法并不安全,因为是个人就可以随便往HDFS上面传文件,近些年,hadoop项目组努力地增加权限,修复这个漏洞。


方法2 :更简单的方法【暂时失败了】

用的copyToLocalFile方法

@Test
	public void testDownLoad() throws IllegalArgumentException, IOException{
		fs.copyToLocalFile(new Path("/in.log"), new Path("c://44444"));
	}

删除一个HDFS上的文件:

@Test
	public void testDel() throws Exception, IOException{
		boolean flag = fs.delete(new Path("/in.log"), false);
		System.out.println(flag);
	}

创建一个HDFS目录:

@Test
	public void testMkdir() throws IllegalArgumentException, IOException{
		boolean mkdirs = fs.mkdirs(new Path("/itcast0106"));
		System.out.println("mkdirs");
	}

用删除文件的方式删除空目录,是可以的。


但是如果我在itcast0106里面上传了文件之后,再删除。报错了。需要在删除那个false换成true【递归删除成功】








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值