hdfs api读写文写件个人练习
看下hdfs的读写原理,主要是打开FileSystem,获得InputStream or OutputStream;
那么主要用到的FileSystem类是一个实现了文件系统的抽象类,继承来自org.apache.hadoop.conf.Configured,并且实现了Close able接口,可以适用于如本地文件系统file://,ftp,hdfs等多种文件系统,所以呢
若是自己要实现一个系统可以通过继承这个类,做出相应的配置,并且实现相应的抽象方法;
public abstract class FileSystem extends Configured implements Closeable {
public static FileSystem get(Configuration conf) throws IOException {
return get(getDefaultUri(conf), conf);
}
public static URI getDefaultUri(Configuration conf) {
return URI.create(fixName(conf.get(FS_DEFAULT_NAME_KEY, DEFAULT_FS)));
}
public static FileSystem get(URI uri, Configuration conf) throws IOException {
String scheme = uri.getScheme();
String authority = uri.getAuthority();
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
}
}
String disableCacheName www.xycheng178.com= String.format("fs.%s.impl.disable.cache", scheme);
if (conf.getBoolean(disableCacheName, false)) {
return createFileSystem(uri, conf);
}
return CACHE.get(uri, conf);
}
}
从部分源码看下,get方法根据conf获取具体的文件系统对象,,而get(uri,conf)方法基于uri和conf创建文件系统对象;
那么看一个简单的应用,用java的api打开一个文件,并且打印出来
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.Path;
public class OpenMethod {
public static void main(String args[]) throws Exception{
Configuration conf = new Configuration();
conf.set("fs.defaultFs", "hdfs://10.192.4.33:9000/");//配置conf
FileSystem fs = FileSystem.get(conf);//根据创建FileSystem对象
Path path = new Path("/home/overshow/hehe.txt");
FSDataInputStream fis = fs.open(path);
byte b[] = new byte[200];
int i = fis.read(b);
System.out.println(new String(b,0,i));
}
}
这里还有三个需要注意的类,一个是Path,一个是FSDataInputStream,一个是conf
let me show you something
first: Configuration
public class Configuration implements Iterable<Map.Entry<String,String>>,Writable {
public void set(String name, String value) {
set(name, value, www.ysyl157.com null);
}
/**
* Set the <code>value</code> of the <www.mcyllpt.com code>www.dasheng178.com name</code> property. If
* <code>name</code> is deprecated, it also sets the <code>value</code> to
* the keys that replace the deprecated key. Name will be trimmed before put
* into configuration.
*
* @param name property name.
* @param value property value.
* @param source the place that this configuration value came from
* (For debugging).
* @throws IllegalArgumentException when the value or name is null.
*/
}
这个类是作业的配置信息类,通过Configuration可以实现在多个mapper和多个reducer任务之间共享信息,所以任何作用的配置信息必须通过Configuration传递,该类实现了Iterable和Writable两个接口,首先Iterable是迭代出Configuration对象加载到内存中的所有name-value键值对。而Writable是为了实现hadoop框架要求的序列化,可以将内存中的name-value序列化到硬盘;其中的set方法设置Configuration的名称和链接;
而Path类继承了fs类,
public class Path implements www.michenggw.com/ Comparable {
private void checkPathArg( String path ) throws IllegalArgumentException {
// disallow construction of a Path from an empty string
if ( path == null ) {
throw new IllegalArgumentException(
"Can not create a Path from a null string");
}
if( path.length() =www.leyouzaixian2.com= 0 ) {
throw new IllegalArgumentException(
"Can not create a Path from an empty string");
}
}
/** Construct a path from a String. Path strings are URIs, but with
* unescaped elements and some additional normalization. */
public Path(String pathString) throws IllegalArgumentException {
checkPathArg( pathString );
// We can't use 'new URI(String)' directly, since it assumes things are
// escaped, which we don't require of Paths.
// add a slash in front of paths with Windows drive letters
if (hasWindowsDrive(pathString) && pathString.charAt(0) != '/') {
pathString = "/" + pathString;
}
// parse uri components
String scheme = null;
String authority = null;
int start = 0;
// parse uri scheme, if any
int colon = pathString.indexOf(':');
int slash = pathString.indexOf('/');
if ((colon != -1) &&
((slash == -1) || (colon < slash))) { // has a scheme
scheme = pathString.substring(0, colon);
start = colon+1;
}
// parse uri authority, if any
if (pathString.startsWith("//", start) &&
(pathString.length()-start > 2)) { // has authority
int nextSlash = pathString.indexOf('/', start+2);
int authEnd = nextSlash > 0 ? nextSlash : pathString.length();
authority = pathString.substring(start+2, authEnd);
start = authEnd;
}
// uri path is the rest of the string -- query & fragment not supported
String path = pathString.substring(start, pathString.length());
initialize(scheme, authority, path, null);
}
/**
* Construct a path from a URI
*/
public Path(URI aUri) {
uri = aUri.normalize(www.hengy178.com);
}
}
好吧,其实就是设置了hdfs的地址;
最后一个类,FSDataInputStream,额,不想看,太长了,
用fs的open方法创建一个FSDataInputStream类的实例,然后简单来说,读文件的流程就是,客户端到最近的(Namenode说了算)DATa Node上调用FSDataInputStream的read方法,通过反复的调用read方法,将数据从DataNode传递到客户端。
值得一提的是,它创建string的那个构造方法,我找了半天源码,似乎是这个,
public String(byte bytes[www.mengzhidu178.com], int offset, int length) {
checkBounds(bytes, offset,www.gangchengyuLe178.com length);
this.value = StringCoding.decode(bytes, offset, length);
}
/**
* Constructs a new {@code String} by decoding the specified array of bytes
* using the platform's www.yongxinzaixian.cn default charset. The length of the new {@code
* String} is a function of the charset, and hence may not be equal to the
* length of the byte array.
*
* <p> The behavior of this constructor when the given bytes are not valid
* in the default charset is unspecified. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
*
* @param bytes
* The bytes to be decoded into characters
*
* @since JDK1.1
**/
#######################################################################
写文件流程差不多一致,不过用到的是另外一个输出流的类FSDataOutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
public class Create_Method {
public static void main(String args[]) throws Exception{
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://10.192.4.33:9000/");
FileSystem fs = FileSystem.get(conf);
FSDataOutputStream fos = fs.create(new Path("/words.txt"));
fos.writeChars("hello world");
}
}
当然,fs还有一个用处就是查看文件目录,但是注意它的类型,是一个特殊的可迭代对象;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.RemoteIterator;
public class listStatus {
public static void main(String args[])throws Exception{
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://10.192.4.33:9000/data");
FileSystem fs = FileSystem.get(conf);
Path path = new Path("/");
RemoteIterator<LocatedFileStatus> list = fs.listFiles(path, true);
while(list.hasNext()) {
System.out.println(list.next());
}
}
}
看下listFiles方法的源码
public RemoteIterator<LocatedFileStatus> listFiles(
final Path f, final boolean recursive)
throws FileNotFoundException, IOException {
return new RemoteIterator<LocatedFileStatus>() {
private Stack<RemoteIterator<LocatedFileStatus>> itors =
new Stack<RemoteIterator<LocatedFileStatus>>();
private RemoteIterator<LocatedFileStatus> curItor =
listLocatedStatus(f);
private LocatedFileStatus curFile;
@Override
public boolean hasNext() throws IOException {
while (curFile == null) {
if (curItor.hasNext()) {
handleFileStat(curItor.next());
} else if (!itors.empty()) {
curItor = itors.pop();
} else {
return false;
}
}
return true;
}
/**
* Process the input stat.
* If it is a file, return the file stat.
* If it is a directory, traverse the directory if recursive is true;
* ignore it if recursive is false.
* @param stat input status
* @throws IOException if any IO error occurs
*/
hdfs api读写文写件个人练习的更多相关文章
- Swagger解决你手写API接口文档的痛
首先,老规矩,我们在接触新事物的时候, 要对之前学习和了解过的东西做一个总结. 01 痛 苦 不做.不行 之前,前后端分离的系统由前端和后端不同的编写,我们苦逼的后端工程师会把自己已经写完的A ...
- CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)
继上一版本V1.3版本发布到现在,时隔N天了:[V1.3版本开源见:CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源] N天的时间,根据各路网友的反映及自身的想法,继续修改优化着本框架,力 ...
- API的文档自动生成——基于CDIF的SOA基本能力
当前,作为大部分移动app和云服务后台之间的标准连接方式,REST API已经得到了绝大部分开发者的认可和广泛的应用.近年来,在新兴API经济模式逐渐兴起,许多厂商纷纷将自己的后台业务能力作为REST ...
- RESTful API接口文档规范小坑
希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 前后端分离的开发模式,假如使用的是基于RESTful API的七层通讯协议,在联调的时候,如何避免配合过程中出现问 ...
- Hadoop学习之路(十)HDFS API的使用
HDFS API的高级编程 HDFS的API就两个:FileSystem 和Configuration 1.文件的上传和下载 package com.ghgj.hdfs.api; import org ...
- Api接口文档管理工具,你知道哪些呢?
上周看到有人在我的Github开源项目中提了个issue,说是否考虑接入swagger.那今天我就用swagger与其他接口文档工具做对比,同时说说Api接口文档工具的那点事.如今,在前后端分离开发的 ...
- Hadoop之HDFS文件读写过程
一.HDFS读过程 1.1 HDFS API 读文件 Configuration conf = new Configuration(); FileSystem fs = FileSystem.get( ...
- Openstack api 学习文档 & restclient使用文档
Openstack api 学习文档 & restclient使用文档 转载请注明http://www.cnblogs.com/juandx/p/4943409.html 这篇文档总结一下我初 ...
- hadoop: hdfs API示例
利用hdfs的api,可以实现向hdfs的文件.目录读写,利用这一套API可以设计一个简易的山寨版云盘,见下图: 为了方便操作,将常用的文件读写操作封装了一个工具类: import org.apach ...
随机推荐
- C# 语句 分支语句
语句是指程序命令,按照顺序执行.可以分为 顺序语句 分支语句 循环语句 之前学习的内容都是按照顺序程序执行的,称之为顺序语句. 今天学的的内容是分支语句. 语句可以嵌套,可以是以分号结尾的单行 ...
- OpenGL列主元矩阵和列主序存储
OpenGL矩阵要考虑两个点,一个是向量如何排布,一个是矩阵如何存储和恢复. 1.排布 排布决定了运算的顺序.OpenGL使用的是列主元,它的意思就是一个4X4的矩阵是由4个列向量构成(这里的v1,v ...
- python基础一 day14 生成器函数进阶
def generator(): print(123) content = yield 1 print('=======',content) print(456) arg = yield 2 '''' ...
- CeontOS6.5安装php环境
港湾云主机重装操作系统之后xshell无法连接:重启ssh:# service sshd restart -bash: vim: command not found:输入 rpm -qa|grep v ...
- js模块化AMD、CMD、ES6
AMD CMD ES6模块化 各个模块化规范对比理解 一.AMD 在上一篇js模块化入门与commonjs解析与应用中详细的解析了关于commonjs模块化规范,commonjs采用的用同步加载方式, ...
- 获取 request 中 json 数据
import java.io.IOException; import javax.servlet.http.HttpServletRequest; /** * request 对象的相关操作 * @a ...
- initWithNibName:bundle awakeFromNib 区别
initWithNibName:bundle 定义:is a message sent to a view (or window) controller in order to create the ...
- UINavgationController
UINavigationBar和UINavigationItem是iOS开发中常用的控件. 1.设置导航栏标题 self.title = @"iOS开发:iOSDevTip"; ...
- hihoCoder第一周---最长回文子串(1032)
其实这就是mancher算法的板子题,贴个代码好了. 思想请见我的另一篇博客: https://blog.csdn.net/qq_41090676/article/details/86768361 # ...
- 【数论 dp】2048
考场上一个DFS优化乱加就对了一个无解的点 题目描述 给定一个长度为 n 的数列,在这个数列中选取一个子序列使得这个子序列中的数能合出2048 对于合并操作,可以选择这个序列中的任意两个数进行合并,当 ...