到目前为止我们的Hadoop完全分布式系统已经搭建完成,现在就是要通过编程来操作Hadoop了,由于Hadoop是基于java语言开发的,自然离不开Eclipse,今天我们就来配置Hadoop的Eclipse开发环境。
由于我的电脑已经安装了Eclipse了,所以这里就不再介绍Eclipse的安装过程了。给出一个Eclipse的官方地址,
https://www.eclipse.org/downloads/download.php?file=/oomph/epp/oxygen/R2/eclipse-inst-win64.exe。我是win7, 64bit的。大家可以自己下载文件然后安装。注意在安装Eclipse的时候,需要先安装jdk工具,然后配置环境变量。
我们在win7中安装好Eclipse之后,直接双加exe文件打开。然后我们新建第一个java程序。
File->Project->java Project
在Project name中输入自己的工程名字->finish
选择src,右键New->class,记得勾选public static void main(String[] args) -> Finish
输入下面的代码
public class Helloworld {
public static void main(String[] args) {
System.out.println("hello world");
}
}
选择"Run"或者快捷键Ctrl+F11来运行一下
可以打印出来hello world
现在我们来操作一下hadoop,在操作hadoop的时候,我们需要先把hadoop的源码包关联到我们的src下面。在Helloworld的工程新建一个libs的文件夹,用来存放我们的hadoop的源码包。
到hadoop的源码包中把所有的jar包都拷到libs中,这些jar包是不包含test包和source包的。然后选中所有的jar包,右键->Build
Path-> Add to build path。之后等待关联tar,然后我们可以看到下面的内容。
这样我们就关联好tar包。然后我们输入下面的代码测试一下。
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import java.io.FileOutputStream;
/*
* 通过API访问hdfs文件系统
*
*
* */
public class TestHDFS {
public static void main(String[] args) throws Exception{
//注册协议处理器工厂,让java程序能够识别hdfs协议
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
//定义URL地址
String url = "hdfs://s201:8020/user/ubuntu/data/hadoop-2.7.2.tar.gz";
//URL对象
URL u = new URL(url);
//URL链接
URLConnection conn = u.openConnection();
//打开输入流
InputStream is = conn.getInputStream();
//输出流
FileOutputStream fos = new FileOutputStream("d:/hadoop-2.7.2.tar.gz");
//对拷贝
byte[] buf = new byte[1024];
int len = -1;
while((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
is.close();
fos.close();
System.out.println("over");
}
}
上面这段代码是把hdfs上面的hadoop-2.7.2.tar.gz包下载到本地的D盘。成功后打印over
我们看到,虽然已经成功打印“over”,而且在D盘也有了hadoop-2.7.2.tar.gz,但是有一个红色的警告,我们看着还是不舒服,
因此现在我们想办法把3个warn去掉。这3个warn是因为log4j日志的问题,因为Hadoop的日志是log4j格式的,因此我们需要把一个
配置文件放在src的根目录下,这个配置就是log4j.properties,它在hadoop-2.7.2\etc\hadoop\,大家可以自己找找,找到后放在src下,
我们再运行就不会出现warn了。
下面我们来试试hdfs的增删改操作。
新建一个package,wilson_packages,然后新建一个class:TestFileSystem,输入下面的代码
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.hadoop.io.IOUtils;
import java.lang.reflect.Method;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.sym.Name;
/*
* 使用Hadoop的文件系统实现文件读取
* */
public class TestFileSystem {
private FileSystem fs;
@Before
public void iniConf() {
try {
Configuration conf = new Configuration();
fs = FileSystem.get(conf);
} catch (Exception e) {
}
}
/*
* 写操作
*
* */
@Test
public void writeFile() throws Exception{
//Configuration conf = new Configuration();
//FileSystem fs = FileSystem.get(conf);
Path path = new Path("hdfs://s201:8020/user/hello_2.txt");
//数据输出流,设置2个副本
FSDataOutputStream dos = fs.create(path, (short)2);
dos.write("helloworld".getBytes());
dos.close();
System.out.println("write file success");
}
/*
* 读操作,从hdfs下载文件
*
* */
@Test
public void readFile() throws Exception {
Path path = new Path("/user/ubuntu/data/hello.txt");
FSDataInputStream fis = fs.open(path);
FileOutputStream fos = new FileOutputStream("d:/hello.txt");
IOUtils.copyBytes(fis, fos, 1024);
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
System.out.println("read file success");
}
/*
* 新建目录
*
* */
@Test
public void mkdir() throws Exception {
Path path = new Path("/user/myfolder");
//创建权限对象
FsPermission perm = new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL);
boolean b = fs.mkdirs(path, perm);
System.out.println(b);
}
/*
* 遍历FileStatus所有不要参数的方法
* */
@Test
public void fileStatus() throws Exception {
FileStatus fs0 = fs.getFileStatus(new Path("/"));
Class clazz = FileStatus.class;
Method[] ms = clazz.getDeclaredMethods();
for(Method m : ms) {
String mname = m.getName();
Class[] ptype = m.getParameterTypes();
if(mname.startsWith("get") && (ptype == null || ptype.length == 0)) {
if(!mname.equals("getSymlink")) {
Object ret = m.invoke(fs0, null);
System.out.println(mname + "() = " + ret);
}
}
}
}
/*
* 遍历整个文件目录
* */
@Test
public void recursiveHdfs() throws Exception {
FileStatus fsroot = fs.getFileStatus(new Path("/"));
print(fsroot);
}
private void print(FileStatus fs0) {
try {
Path p = fs0.getPath();
//
System.out.println(p.toUri().getPath());
if(fs0.isDirectory()) {
//列出路径下的所有资源
FileStatus[] fss = fs.listStatus(p);
if(fss != null && fss.length > 0) {
for(FileStatus ff: fss) {
print(ff);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 删除文件或者文件夹
*
* */
@Test
public void deleteFile() throws Exception {
Path p = new Path("/user/hello.txt");
fs.delete(p, true);
}
}
大家可以自己试试上面的能不能运行成功,其中可能会报一个错误,expected:file///的错误。
这是因为Hadoop默认的模式本地模式,因此它希望的文件目录是file:///形式的,我们需要在src的根目录下面手动新建一个
core-site.xml文件,然后输入下面的代码
<?xml version="1.0"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://s201:8020/</value>
</property>
</configuration>
这样再运行就不会有问题了。
下面来介绍一个hadoop的Eclipse插件,这个插件可以帮助我们很方便的操作Hadoop的文件系统。
首先在网上下载它的zip包,名字是hadoop2x-eclipse-plugin-master.zip,给大家一个地址
https://github.com/winghc/hadoop2x-eclipse-plugin。然后解压,在release中有3个tar包
- hadoop-eclipse-kepler-plugin-2.2.0.jar
- hadoop-eclipse-kepler-plugin-2.4.1.jar
- hadoop-eclipse-plugin-2.6.0.jar
点击Hadoop Map/Reduce,在右侧输入hadoop的安装目录,我们在windows中并没有安装hadoop,这里输入刚才存放3个tar包
的地址就可以了,只输入到hadoop-2.7.2这一级,Apply->Apply and Close
点击右侧的open perspective,就是这个图标,选择Map/Reduce,在project下应该会出现一个DFS Locations的目录
然后在下面的空白区域右键->New Hadoop Location
Location name随便取名字,Host选择我们的namenode的主机名或者IP地址,DFS Master的port填入8020,即hadoop的IPC
端口,Finish
回到Project区域的DFS Locations我们应该能看到下面的样子
这样我们就可以方便的查看和操作HDFS的文件系统了,不必再编写代码执行增删改查了。
以上就是今天的全部内容
与您共勉