011_Eclipse中使用HDFSFileSystemAPI事例介绍
需求
1.文件操作
1)上传本地文件到HDFS
2)读取文件
3)在hadoopfs中新建文件,并写入
4)重命名文件
5)删除hadoopfs上的文件
2.目录操作
1)读取某个目录下的所有文件
2)在hadoopfs上创建目录
3)删除目录
3. HDFS信息
1)查找某个文件在HDFS集群的位置
2)获取HDFS集群上所有节点名称信息
准备工作:
1、新建一个project项目,添加lib文件夹,将图示的jar文件添加到文件夹中,并将其add to built path。如图示。
2、添加conf文件夹,将core-site.xml和hdfs-site.xml两个文件拷贝到conf下面。刷新。主要作用是配置主机地址。
3、编译环境和运行环境都是用1.7版本,即jdk1.7和jre1.7。本实验使用的是Eclipse indigo-windows-32bit和jdk1.7-32bit。
4、此处暂时不需要hadoop-plugin插件,有的话也不影响,但是主机hosts文件要配置好,就是在主机cmd命令中可以通过域名访问CentOS端NameNode主机。
HDFS 文件读取流程
1.Client调用FileSystem.open()方法:
1)FileSystem通过RPC与NN通信,NN返回该文件的部分或全部block列表(含有block拷贝的DN地址)。
2)选取距离客户端最近的DN建立连接,读取block,返回FSDataInputStream。
2.Client调用输入流的read()方法:
1)当读到block结尾时,FSDataInputStream关闭与当前DN的连接,并为读取下一个block寻找最近DN。
2)读取完一个block都会进行checksum验证,如果读取DN时出现错误,客户端会通知NN,然后再从下一个拥有该block拷贝的DN继续读。
3)如果block列表读完后,文件还未结束,FileSystem会继续从NN获取下一批block列表。
3.关闭FSDataInputStream
HDFS 文件写入流程
1.Client调用FileSystem的create()方法:
1)FileSystem向NN发出请求,在NN的namespace里面创建一 新文件,但是并不关联任何块。
2)NN检查文件是否已存在、操作权限。如果检查通过,NN记录新文件信息,并在某一个DN上创建数据块。
3)返回FSDataOutputStream,将Client引导至该数据块执行写入操作。
2.Client调用输出流的write()方法:HDFS默认将每个数据块放置3份。
FSDataOutputStream将数据首先写到第一节点,第一节点将数据包传送并写入第二节点,第二节点=》第三节点。
3.Client调用流的close()方法:flush缓冲区的数据包,block完成复制份数后,
NN返回成功消息。
代码如下:
1、添加一个包(packet),org.dragon.hadoop.hdfs.utils,添加一个HDFSUtils.java文件,文件里面内容如下
package org.dragon.hadoop.hdfs.utils; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; /** * @author ZhuXY * @time 2016-3-6 下午8:17:10 */ public class HDFSUtils { public static FileSystem getFileSystem() throws IOException, Exception { // 获取配置 Configuration conf = new Configuration(); // 获取文件系统 FileSystem hdfs = FileSystem.get(conf); return hdfs; } }
2、下面就是文件操作的正式内容,其中就行Junit 4进行测试,Junit添加直接可以,网上教程很多,将此库文件包含到项目中就可以了。
代码中算法列表:
package org.dragon.hadoop.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; 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.hdfs.DistributedFileSystem; import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.io.IOUtils; import org.dragon.hadoop.hdfs.utils.HDFSUtils; import org.junit.Test; /** * @author ZhuXY * @time 2016-3-6 下午5:57:53 通过FileSystem API 操作HDFS */ /** * 步骤:1、将5个jar包考到lib目录下 * 2、新建一个conf文件夹,然后将core-site.xml和hdfs-site.xml两个文件考到其下 * 原因:添加配置文件信息识别文件系统 * 3、创建一个文件系统 * 4、 打开输出流 * 5、read * 6、close * @author ZhuXY * */ public class HDFSFsTest { //读取当前系统中的文件 @Test public void testRead() throws Exception { // 获取配置 Configuration conf = new Configuration(); // 获取文件系统 FileSystem hdfs = FileSystem.get(conf); // 文件名称 Path path = new Path("/opt/input/touch3.data"); // 打开文件输入流----------open FSDataInputStream instream = hdfs.open(path); // 读取文件到控制台显示--------read IOUtils.copyBytes(instream, System.out, 4096, false); // 关闭流---------------close IOUtils.closeStream(instream); } //列出当前文件和目录 @Test public void testList() throws Exception { // 获取配置 Configuration conf = new Configuration(); // 获取文件系统 FileSystem hdfs = FileSystem.get(conf); Path path = new Path("/wc"); FileStatus[] fileStatus = hdfs.listStatus(path); for (FileStatus fs : fileStatus) { Path p = fs.getPath(); String info = fs.isDir() ? "目录" : "文件"; // System.out.println("5"); System.out.println(info + ":" + p); } } //对上传的文件重命名 @Test public void testRename() throws Exception{ FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //HDFS 文件上传路径 Path srcPath=new Path("/opt/input/touch3.data"); Path destPath=new Path("/opt/input/rename.data"); boolean flag=fsFileSystem.rename(srcPath, destPath); System.out.println(flag); } //创建文件,连同目录一起创建 @Test public void testCreate() throws Exception{ FileSystem hdfsFileSystem=HDFSUtils.getFileSystem(); //HDFS文件上传路径 Path path=new Path("/wc/test/touch.data"); //创建文件,并获取输出流 FSDataOutputStream fsDataOutputStream=hdfsFileSystem.create(path); //通过输出流写入数据 // fsDataOutputStream.writeUTF("你好,hadoop!"); fsDataOutputStream.write("你好".getBytes()); fsDataOutputStream.writeUTF("hadoop!"); IOUtils.closeStream(fsDataOutputStream); } //删除文件 @Test public void testRemove() throws Exception{ FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path path=new Path("/opt/input/touch3.data"); boolean flag=fsFileSystem.deleteOnExit(path); System.out.println(flag); } //删除目录 @Test public void testRemoveDir() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path path=new Path("/opt/input/"); boolean flag=fsFileSystem.delete(path,true); System.out.println(flag); } //上传文件---put copyFromLocal @Test public void testPut() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); Path srcPath=new Path("C:/jdk-8u73-linux-x64.tar.gz"); //HDFS上传文件路径 Path destPath=new Path("/wc/123/"); //此处目录如果不存在会保存在/wc目录下,取名123 fsFileSystem.copyFromLocalFile(srcPath, destPath); } //查看某个文件在HDFS集群中的位置 @Test public void testLocation() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //HDFS上传文件路径 Path path=new Path("/wc/123/"); FileStatus fsFileStatus=fsFileSystem.getFileStatus(path); //获得所有的块所在的位置信息包括:主机名,块名称、块大小etc BlockLocation[] blockLocations=fsFileSystem.getFileBlockLocations(fsFileStatus,0,fsFileStatus.getLen()); for(BlockLocation blockLocation:blockLocations){ String[] hostStrings=blockLocation.getHosts();//获取所在的主机 //System.out.println(hostStrings);//这样写不行 //System.out.println(hostStrings[0]);//这样写可以 for(String host:hostStrings) System.out.println(host); } } //获取集群中所有的节点的名称信息 @Test public void testCluster() throws Exception { FileSystem fsFileSystem=HDFSUtils.getFileSystem(); //将文件系统强制转换为分布式文件系统 DistributedFileSystem distributedFileSystem=(DistributedFileSystem)fsFileSystem; //获取文件系统中数据状态信息 DatanodeInfo[] datanodeInfos=distributedFileSystem.getDataNodeStats(); //循环遍历 for(DatanodeInfo datanodeInfo:datanodeInfos){ String hostnameString=datanodeInfo.getHostName(); System.out.println(hostnameString); } } }
学习内容
1、学习使用代码追踪工具,光标移动到类名,然后按住Ctril键出现小手的时候,单击,然后Attach Source就可以了,可以使源码文件,还是不如行的话重启一下Eclipse就行了,实验中遇到这种情况。
2、学习快捷键的使用,注释alt+/,将一行代码上移一行alt+|(向上箭头),复制上移ctril+alt+|(向上箭头),删除一行Ctrl+d,快速对齐Ctrl+shift+F,打开源码搜素open type Ctrl+shift+T,打开outline是ctrl+o等。
3、特别注意的是core-site.xml中的主机地址一定要配置好。