[小试牛刀] - Hadoop文件操作
来源:互联网 发布:python wxpython 教程 编辑:程序博客网 时间:2024/06/06 17:06
- 博由
- HDFS
- URL访问方式
- FileSystem
- pomxml配置
- 参考
博由
上一篇简单操作了一下WordCount的实现,第一个Hadoop程序;在Hadoop中比较核心内容有: [1] dfs 分布式文件系统 [2] MapReduce 主要想了解一下Hadoop的分布式文件系统。
HDFS
HDFS:Hadoop Distribute File System(Hadoop分布式文件系统); 文件系统结构是Master/Slave结构。 [1] NameNode: 担当的就是Master节点,一个集群只有一个NameNode,其主要负责管理命名空间、block隐射关系、配置副本策略、处理客户端请求等功能。 [2] SecondaryNameNode: 是Master的一个冷备份,与NameNode进行通讯以降低当NameNode出现故障时,可以降低损失。 [3] DataNode: Slave节点,或者说是工作节点,是真实block块存放的地方; 目前在初级阶段,但是可以分为read和write两种方式,来描述hdfs集群的运行结构,这里直接介绍java代码的操作和命令行的操作,之后再了解一下read/write client,Namenode,DataNode是如何交互的。
URL访问方式
package com.hadoop.hello.io;import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;import org.apache.hadoop.io.IOUtils;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;/** * 通过java.net.URL操作文件流,需要特别注意的是默认URL无法识别hdfs协议的文件, * 需要设置URL流的处理方式,使用FsURLSteamHandlerFactory工厂来识别处理。但是 * 这里会又一个比较大的缺陷就是: * URL.setURLStreamHandlerFactory 只能设置一次在一个jvm环境下,因此如果有其他地方设置了 * URL.setURLStreamHandlerFactory 那么意味着无法无法处理 * Created by wangzhiping on 17/1/10. */public class ReadFromHadoopByNetUrl { static { // 设置URL Stream处理器工厂 URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); } public static void main(String[] args){ InputStream in = null; try { // 如果直接使用URL无法识别hdfs协议,需要设置 in = new URL("hdfs://localhost:9000/test/test.txt").openStream(); IOUtils.copyBytes(in, System.out, 4096, false); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
通过java.net.URL访问,但是hdfs协议默认情况下URL无法识别,此时必须设置URL.setURLStreamHandlerFactory为Hadoop的UrlStreamHandlerFactory,但是`public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) { synchronized (streamHandlerLock) { if (factory != null) { throw new Error("factory already defined"); } SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkSetFactory(); } handlers.clear(); factory = fac; }} `每一个JVM一旦被设置了就不能别覆盖,因此如果应用中存在其他URLStreamHandlerFactory的设置,那么这种方法就无法使用了。
FileSystem
Hadoop提供了FileSystem类来操作HDFS,具体使用方式如下:`package com.hadoop.hello.io;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.hdfs.DistributedFileSystem;import org.apache.hadoop.io.IOUtils;import java.io.IOException;import java.io.InputStream;import java.net.URI;import java.net.URISyntaxException;/** * Created by wangzhiping on 17/1/10. */public class ReadFromHadoopByFlieSystem { public static void main(String[] args) { InputStream in = null; // 构建Hadoop配置类,会默认加载core-site.xml,core-default.xml等配置文件 Configuration cfg = new Configuration(); FileSystem fs = null; try { // 这里必须使用URI来解析schema为hdfs,默认是file:// ,fs.defaultFS,会根据hdfs从core-site.xml // 和 core-default.xml 找 fs.hdfs.impl /** * <property> * <name>fs.hdfs.impl</name> * <value>org.apache.hadoop.hdfs.DistributedFileSystem</value> * <description>The FileSystem for hdfs: uris.</description> * </property> */ fs = FileSystem.get(new URI("hdfs://localhost:9000/"), cfg); if(fs instanceof DistributedFileSystem){ // fs返回就是这个类 System.out.print("------dfs-----"); } in = fs.open(new Path("hdfs://localhost:9000/test/test.txt")); IOUtils.copyBytes(in, System.out, 4096, false); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } finally { IOUtils.closeStream(fs); IOUtils.closeStream(in); } }}`通过FileSystem.get获取FileSystem实例,实际上内部是反射机制创建了DistributeFileSystem类.`public static FileSystem get(URI uri, Configuration conf) throws IOException { // 根据给出的hdfs Master地址,解析出协议和机构 String scheme = uri.getScheme(); String authority = uri.getAuthority(); // 默认是fs.defaultFS 也就是file:// if (scheme == null && authority == null) { // use default FS return get(conf); } if (scheme != null && authority == null) { // no authority URI defaultUri = getDefaultUri(conf); if (scheme.equals(defaultUri.getScheme()) // if scheme matches default && defaultUri.getAuthority() != null) { // & default has authority return get(defaultUri, conf); // return default } } // fs.hdfs.impl.disable.cache 是一个xml配置在core-site.xml或者依赖包中的core-default.xml String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme); if (conf.getBoolean(disableCacheName, false)) { // 这里就是反射创建DistributeFileSystem return createFileSystem(uri, conf); } return CACHE.get(uri, conf); }``private static FileSystem createFileSystem(URI uri, Configuration conf ) throws IOException { // 这里会找fs.hdfs.impl 的实现类是那个,其配置是在core-default.xml Class<?> clazz = getFileSystemClass(uri.getScheme(), conf); FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf); fs.initialize(uri, conf); return fs;}`
获取FileSystem实例之后,就可以进行hdfs相关操作,如下代码简单罗列了一些基本操作,创建文件、删除文件、移动文件等等。
package com.hadoop.hello.io;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataOutputStream;import org.apache.hadoop.fs.FileChecksum;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.fs.permission.FsPermission;import org.apache.hadoop.io.IOUtils;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URI;import java.net.URISyntaxException;import java.util.HashMap;import java.util.Map;/** * Hadoop Distributed File System * FS Shell * Created by wangzhiping on 17/1/11. */public class FileCmdOnHadoop { public final static Configuration cfg = new Configuration(); public static FileSystem fs = null; public final static String HADOOP_URI = "hdfs://localhost:9000"; static { try { fs = FileSystem.get(new URI(HADOOP_URI), cfg); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } public static void closeFileSystem(){ IOUtils.closeStream(fs); } /** * hadoop fs -moveFromLocal <localsrc> <dist> * @param src * @param dist */ public static void moveFromLocal(String src, String dist) { try { fs.moveFromLocalFile(new Path(src), new Path(dist)); } catch (IOException e) { System.out.println("moveLocalToHadoop, exception: " + e); e.printStackTrace(); } } /** * 对应hadoop fs -appendToFile <localsrc> <dist>命令 * 将文件内容条件到目标文件的末尾,可以同时添加多个文件 * @param dist: 目标文件 * @param srcs: 源文件列表 */ public static void appendToFile(String dist, String... srcs) { InputStream in = null; OutputStream out = null; try { out = fs.append(new Path(dist)); for (String src : srcs) { in = new FileInputStream(src); IOUtils.copyBytes(in, out, in.available(), false); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeStream(in); IOUtils.closeStream(out); } } /** * 读取文件内容并查看 * 对应hadoop fs -cat src */ public static void cat(String hdfsPath){ InputStream in = null; try { in = fs.open(new Path(hdfsPath)); IOUtils.copyBytes(in, System.out, in.available(), false); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeStream(in); } } /** * 新建文件夹 * hadoop fs -mkdir * @param path */ public static boolean mkdirs(String path) { try { // 或者通过FsPermession第二个参数,设置文件权限 return fs.mkdirs(new Path(path)); } catch (IOException e) { e.printStackTrace(); } return false; } /** * 删除文件夹 * hadoop fs -rmdir * @param path * @return */ public static void rmdir(String path, boolean recursive) { try { // 删除文件或者文件夹,第二个参数等价于 -r fs.delete(new Path(path), recursive ? true : false); } catch (IOException e) { e.printStackTrace(); } } /** * 创建文件 * @param path */ public static void touchz(String path){ OutputStream out = null; try { out = fs.create(new Path(path)); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeStream(out); } } public static void main(String[] args) { moveFromLocal("/Users/wangzhiping/java_error_in_idea_4468.log", "/test"); appendToFile("/test/test.txt", "/Users/wangzhiping/test.txt"); cat("/test/test.txt"); mkdirs("/test/mkdir_test"); rmdir("/test/mkdir_test", false); touchz("/test/touchz.txt"); }}还有很多的API,其实看下FileSystem源码,就很容易使用了,一点都不难。
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hadoop-learn</groupId> <artifactId>hello</artifactId> <version>1.0-SNAPSHOT</version> <properties> <hadoop.version>2.7.1</hadoop.version> </properties> <dependencies> <!-- 操作hdfs文件系统时,需要引入该包 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-common</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>${hadoop.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-core 注意包引入顺序必须是hadoop-common在前,hadoop-core在后,不然会报错,找不到NoSuchMethod,这个折腾死我了,看了源码才发现还有这一出,因为他们存在相同的类名和包名。 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-core</artifactId> <version>1.2.1</version> </dependency> </dependencies></project>
附包图片:注意坑
参考
[1] https://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html
[2] http://www.cnblogs.com/laov/p/3434917.html
0 0
- [小试牛刀] - Hadoop文件操作
- hadoop文件操作命令
- Hadoop HDFS文件操作
- hadoop文件操作命令
- hadoop 一些文件操作
- Hadoop 文件操作
- 基本hadoop文件操作
- hadoop的文件操作
- hadoop 文件目录操作
- Hadoop文件操作
- <hadoop>文件操作
- Hadoop文件操作
- hadoop 文件操作 接口调用
- hadoop中的文件操作 FileSystem
- kettle实现hadoop文件操作
- hadoop 基本文件操作命令
- Hadoop之HDFS文件操作
- Hadoop文件操作基本命令
- leetcode-260-SingleNumber III
- Layer and LayerFactory in dnn
- Android Volley框架的几种post提交请求方式
- iOS开发-Runtime详解
- 使用base64编码的好处
- [小试牛刀] - Hadoop文件操作
- java中properties配置文件的用法
- 子网掩码所管理网段计算
- Aspose.Words使用word模板中的书签插入图片(导出含有图片的word)
- Java执行定时任务(Timer、Quartz)
- 基于 Open vSwitch 的 OpenFlow 实践
- 设计模式——Factory模式
- Implement Stack using Queues/Implement Queue using Stacks
- Java中 abstract class 与interface的区别