看下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读写文写件个人练习的更多相关文章

  1. Swagger解决你手写API接口文档的痛

    首先,老规矩,我们在接触新事物的时候, 要对之前学习和了解过的东西做一个总结. 01 痛     苦 不做.不行 之前,前后端分离的系统由前端和后端不同的编写,我们苦逼的后端工程师会把自己已经写完的A ...

  2. CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)

    继上一版本V1.3版本发布到现在,时隔N天了:[V1.3版本开源见:CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源] N天的时间,根据各路网友的反映及自身的想法,继续修改优化着本框架,力 ...

  3. API的文档自动生成——基于CDIF的SOA基本能力

    当前,作为大部分移动app和云服务后台之间的标准连接方式,REST API已经得到了绝大部分开发者的认可和广泛的应用.近年来,在新兴API经济模式逐渐兴起,许多厂商纷纷将自己的后台业务能力作为REST ...

  4. RESTful API接口文档规范小坑

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 前后端分离的开发模式,假如使用的是基于RESTful API的七层通讯协议,在联调的时候,如何避免配合过程中出现问 ...

  5. Hadoop学习之路(十)HDFS API的使用

    HDFS API的高级编程 HDFS的API就两个:FileSystem 和Configuration 1.文件的上传和下载 package com.ghgj.hdfs.api; import org ...

  6. Api接口文档管理工具,你知道哪些呢?

    上周看到有人在我的Github开源项目中提了个issue,说是否考虑接入swagger.那今天我就用swagger与其他接口文档工具做对比,同时说说Api接口文档工具的那点事.如今,在前后端分离开发的 ...

  7. Hadoop之HDFS文件读写过程

    一.HDFS读过程 1.1 HDFS API 读文件 Configuration conf = new Configuration(); FileSystem fs = FileSystem.get( ...

  8. Openstack api 学习文档 & restclient使用文档

    Openstack api 学习文档 & restclient使用文档 转载请注明http://www.cnblogs.com/juandx/p/4943409.html 这篇文档总结一下我初 ...

  9. hadoop: hdfs API示例

    利用hdfs的api,可以实现向hdfs的文件.目录读写,利用这一套API可以设计一个简易的山寨版云盘,见下图: 为了方便操作,将常用的文件读写操作封装了一个工具类: import org.apach ...

随机推荐

  1. Objective-C Numbers

    In Objective-C programming language, in order to save the basic data types like int, float, bool in ...

  2. sysdig安装和使用介绍

    安装步骤1)安装资源库rpm --import https://s3.amazonaws.com/download.draios.com/DRAIOS-GPG-KEY.publiccurl -s -o ...

  3. 线程池 Threadlocal 使用注意

    线程池中的线程是重复使用的,即一次使用完后,会被重新放回线程池,可被重新分配使用. 因此,ThreadLocal线程变量,如果保存的信息只是针对一次请求的,放回线程池之前需要清空这些Threadloc ...

  4. UVA 11324 The Largest Clique (强连通分量,dp)

    给出一个有向图,求一个最大的结点集合,任意两个点u,v.u可到达v或v可到达u. 一个强连通分量肯定一起选的.而且只能在一条路径上. 所以先找出所有scc,然后缩点找一条最大权的路径,按拓扑序跑DAG ...

  5. Data truncation: Data too long for column 'id' at row 1

    Caused by: java.sql.BatchUpdateException: Data truncation: Data too long for column 'titleimg' at ro ...

  6. 移动端:active伪类无效的解决方法

    :active伪类常用于设定点击状态下或其他被激活状态下一个链接的样式.最常用于锚点<a href="#">这种情况,一般主流浏览器下也支持其他元素,如button等. ...

  7. tcpdump简单使用

    1.使用wincap将文件放入系统任意路径, 2.进入系统,赋文件可执行权限, 3.输入命令:./tcpdump -i eth0 -s 0 -w xxx.pcap 4.进行数据交互 5.退出程序运行, ...

  8. HITICS || 2018大作业 程序人生 Hello's P2P

    摘  要 本文通过分析一个hello.c的完整的生命周期,从它开始被编译,到被汇编.链接.在进程中运行,讲解了Linux计算机系统执行一个程序的完整过程. 关键词:操作系统,进程,程序的生命周期 目 ...

  9. 关于回顾css发现的一些问题

    1.针对于before和after伪元素的用法: <style> .clearfix:before, .clearfix:after{ clear:both; content:" ...

  10. SniperOJ-leak-advanced-x86-64

    借助DynELF实现无libc的漏洞利用小结 1.leak-advance与leak的区别在于一个可用函数是write,一个可用函数是puts.write比puts更容易利用,虽然write需要的参数 ...