Hadoop(二)

来源:互联网 发布:如何看待网络直播 编辑:程序博客网 时间:2024/05/29 02:52

hdfsjava客户端编程

HDFS客户端编程应用场景:数据采集

日志数据一般生成在公司的业务系统(如web服务器)中

一般以日志文件的形式存在业务系统服务器的磁盘目录中

但是日志文件会随着时间不断增长

因此,需要定期采集到HDFS中,一方面可以让业务服务器的磁盘空间不断得到释放,另一方面,数据汇聚到HDFS后,也便于统一处理分析






windows开发环境中做一些准备工作:

  1. 1.windows的某个路径中解压一份windows版本的hadoop安装包
  2. 2.将解压出的hadoop目录配置到windows的环境变量中:HADOOP_HOME


HDFS客户端API使用

  1. hdfs客户端开发所需的jar导入工程(jar包可在hadoop安装包中找到commonhdfs不仅需要放在外面的jar包,还需要common和hdfs本身自己依赖的lib里面的包
  2. 写代码

要点:要对hdfs中的文件进行操作,代码中首先需要获得一个hdfs的客户端对象

Configuration conf = new Configuration();

FileSystem fs = FileSystem.get(new URI("hdfs://hdp-01:9000"),conf,"root");


  1. 3.利用fs对象的方法进行文件操作

上传文件—— fs.copyFromLocalFile(new Path("本地路径"),new Path("hdfs的路径"));

下载文件——fs.copyToLocalFile(new Path("hdfs的路径"),new Path("本地路径"))



获取HDFS客户端对象的代码:

//想要获取客户端对象,就需要构造一个configuration对象Configuration conf = new Configuration();//需要制定hdfs文件系统,同时指定namenode所在的机器conf.set("fs.defaultFS","hdfs://hdp-01:9000");//副本数量和blk大小conf.set("dfs.replication", "2");conf.set("dfs.blocksize", "64m");//想要操作hdfs,就需要有一个客户端对象FileSystem fs = FileSystem.get(conf);fs.copyFromLocalFile(new Path("/Users/yoofale/Desktop/logs.txt"), new Path("/"));fs.close();}
此时运行会报错

是因为作为本机没有权限进行操作。此时需要伪装成root用户进行操作

第一种解决方式:


设置运行程序的参数

第二种解决方式:

将参数设置到系统JVM里面去

要在FileSystem生成前设置,否则读取的就是本机。

第三种解决方式:


hdfs客户端常用功能使用

先写一段junitbefore

@Beforepublic void init() throws Exception {Configuration conf = new Configuration();// 需要制定hdfs文件系统,同时指定namenode所在的机器conf.set("fs.defaultFS", "hdfs://hdp-01:9000");conf.set("dfs.replication", "2");conf.set("dfs.blocksize", "64m");fs = FileSystem.get(new URI("hdfs://hdp-01:9000"), conf, "root");}

上传文件

fs.copyFromLocalFile(src,dest)

@Testpublic void testPut() throws Exception {fs.copyFromLocalFile(new Path("/Users/yoofale/Desktop/logs.txt"), new Path("/10.18"));fs.close();}


下载文件

fs.copyToLocalFile(src,dst)

public void testGet() throws Exception {fs.copyToLocalFile(new Path("/66.txt"), new Path("/Users/yoofale/Desktop/我是C盘"));fs.close();}


注意:

windows平台上使用hdfs客户端下载文件,那么客户端就需要往windows的文件系统中写入文件,需要调用hadoopwindows开发的本地平台工具,就需要在windows系统中配置一个HADOOP_HOME,指向的安装包是一个在windows平台上编译的安装包,里面有大量的本地平台工具库。



创建目录

fs.mkdirs(Path path);

@Testpublic void testmkdir() throws Exception {//fs.mkdirs(new Path("/yun"));fs.close();}



移动/修改目录名称

fs.rename(Path src,Path dst)

// 移动文件@Testpublic void testmv() throws Exception {// 重命名就是移动fs.rename(new Path("/66.txt"), new Path("/yun/77.txt"));fs.close();}



删除文件或目录

如果不使用递归,不能删除非空目录

fs.delete(Path path ,boolean recursive)

@Testpublic void testrm() throws Exception {fs.delete(new Path("/10.18"), true);fs.close();}



判断一个路径是否存在

fs.exists(Path path)

// 判断是否存在@Testpublic void testexist() throws Exception {//boolean exists = fs.exists(new Path("/yun/77.txt"));System.out.println(exists);fs.close();}



读取文件内容

FSDataInputStream in = fs.open(Path path);

// 读文件@Testpublic void testcat() throws Exception {// 通过fs 获取一个data的输入流FSDataInputStream open = fs.open(new Path("/yun/77.txt"));// 把这个data输入流转换为字符流BufferedReader bf = new BufferedReader(new InputStreamReader(open));String line = null;while ((line = bf.readLine()) != null) {System.out.println(line);}bf.close();open.close();fs.close();}



往文件中写入数据

FSDataOutputStream out = fs.create(Path path,boolean overwrite);

out.write("xxx".getBytes());


// 写文件@Testpublic void testwrite() throws Exception {// 通过fs 获取一个data的输入流 // 多次写,默认会覆盖FSDataOutputStream fsOut = fs.create(new Path("/yun/88.txt"));// // 设置为不覆盖// FSDataOutputStream fsOut2 = fs.create(new Path("/nvshen/baby.log"),false);// 追加// FSDataOutputStream fsOut = fs.append(new Path("/yun/77.txt"));fsOut.write("i miss qy \n".getBytes());fsOut.write("白日做梦 \n".getBytes("utf-8"));fsOut.close();fs.close();}
此处需要注意creat,true是覆盖,false不会覆盖。已存在一般用append。

定位读取

in.seek(12);

// 随机读文件@Testpublic void testread2() throws Exception {// 通过fs 获取一个data的输入流FSDataInputStream open = fs.open(new Path("/yun/77.txt"));// 指定随机读取的位置open.seek(2);byte[] buff = new byte[10];open.read(buff);System.out.println(new String(buff));open.close();fs.close();}


查看文件信息

fs.listFiles(Path path,Boolean recursive)

listFiles()方法只获取文件信息,不返回文件夹信息

// 查看文件的相关信息@Testpublic void testListFile() throws Exception {// 是否递归RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);while (listFiles.hasNext()) {LocatedFileStatus file = listFiles.next();System.out.println("访问时间:" + file.getAccessTime());System.out.println("块大小:" + file.getBlockSize());System.out.println("文件路径:" + file.getPath());System.out.println("副本数量:" + file.getReplication());BlockLocation[] blockLocation = file.getBlockLocations();System.out.println("---文件块信息----");for (BlockLocation blk : blockLocation) {System.out.println("---块大小=" + blk.getLength());System.out.println("块所在的节点:" + Arrays.toString(blk.getHosts()));System.out.println("块的起始偏移量:" + blk.getOffset());}System.out.println("----------------------");}fs.close();}


查看文件和文件夹信息

fs.listStatus(Path path)

// 查看文件夹的相关信息@Testpublic void testListStatus() throws Exception {FileStatus[] listStatus = fs.listStatus(new Path("/"));for (FileStatus fss : listStatus) {System.out.println("路径:" + fss.getPath());System.out.println(fss.isFile() ? "是文件" : "是目录");System.out.println("所有者:" + fss.getOwner());System.out.println("权限信息:" + fss.getPermission());System.out.println("修改时间:" + fss.getModificationTime());System.out.println(fss.isSymlink()? "是符号链接" : "不是符号链接");System.out.println("修改时间:" + fss.getPermission());}
fs.close(); }



原创粉丝点击