文档章节

使用FileSystem API读取数据

超人学院
 超人学院
发布于 2015/03/16 14:06
字数 1418
阅读 300
收藏 0

精选30+云产品,助力企业轻松上云!>>>

如前一小节所解释的,有时不能在应用中设置URLStreamHandlerFactory。这时,我们需要用FileSystem API来打开一个文件的输入流。

文件在Hadoop文件系统中显示为一个Hadoop Path对象(不是一个java.io.File对象,因为它的语义与本地文件系统关联太紧密)。我们可以把一个路径视为一个Hadoop文件系统URI,如hdfs://localhost/user/tom/quangle.txt

FileSystem是一个普通的文件系统API,所以首要任务是检索我们要用的文件系统实例,这里是HDFS。取得FileSystem实例有两种静态工厂方法:

1.  public static FileSystem get(Configuration conf) 
throws IOException  

2.  ublic static FileSystem get(URI uri, 
Configuration conf) throws IOException 

Configuration对象封装了一个客户端或服务器的配置,这是用从类路径读取而来的配置文件(conf/core-site.xml)来设置的。第一个方法返回的是默认文件系统(conf/core-site.xml中设置的,如果没有设置过,则是默认的本地文件系统)。第二个方法使用指定的URI方案及决定所用文件系统的权限,如果指定URI中没有指定方案,则退回默认的文件系统。

有了FileSystem实例后,我们调用open()来得到一个文件的输入流:

1.  public FSDataInputStream open(Path f) throws IOException  

2.  ublic abstract FSDataInputStream open(Path f, 
int bufferSize) throws IOException 

第一个方法使用默认4 KB的缓冲大小。

将它们合在一起,我们可以在例3-2中重写例3-1

3-2:直接使用FileSystem以标准输出格式显示Hadoop文件系统的文件

1.  public class FileSystemCat {  

2.    public static void main(String[] args) throws Exception {  

3.      String uri = args[0];  

4.      Configuration conf = new Configuration();  

5.      FileSystem fs = FileSystem.get(URI.create(uri), conf);  

6.      InputStream in = null;  

7.      try {  

8.        in = fs.open(new Path(uri));  

9.        IOUtils.copyBytes(in, System.out, 4096, false);  

10.     } finally {  

11.       IOUtils.closeStream(in);  

12.     }  

13.   }  

14.

程序运行结果如下:

1.      % hadoop FileSystemCat hdfs://localhost/user/tom/quangle.txt  

2.  On the top of the Crumpetty Tree  

3.  The Quangle Wangle sat,  

4.  But his face you could not see,  

5.  On account of his Beaver Hat.  

6.  FSDataInputStream 

FileSystem中的open()方法实际上返回的是一个FSDataInputStream,而不是标准的java.io类。这个类是java.io.DataInputStream的一个子类,支持随机访问,这样就可以从流的任意位置读取数据了。

1.      package org.apache.hadoop.fs;  

2.   

3.  public class FSDataInputStream extends DataInputStream  

4.       implements Seekable, PositionedReadable {  

5.       // implementation elided  

6. 

Seekable接口允许在文件中定位,并提供一个查询方法,用于查询当前位置相对于文件开始处的偏移量(getPos())

1.  public interface Seekable {  

2.    void seek(long pos) throws IOException;  

3.    long getPos() throws IOException;  

4.    boolean seekToNewSource(long targetPos) throws IOException;  

5. 

调用seek()来定位大于文件长度的位置会导致IOException异常。与java.io.InputStream中的skip()不同,seek()并没有指出数据流当前位置之后的一点,它可以移到文件中任意一个绝对位置。

应用程序开发人员并不常用seekToNewSource()方法。此方法一般倾向于切换到数据的另一个副本并在新的副本中寻找targetPos指定的位置。HDFS内部就采用这样的方法在数据节点故障时为客户端提供可靠的数据输入流。

3-3是例3-2的简单扩展,它将一个文件两次写入标准输出:在写一次后,定位到文件的开头再次读入数据流。

3-3:通过使用seek两次以标准输出格式显示Hadoop文件系统的文件

1.  public class FileSystemDoubleCat {  

2.   

3.    public static void main(String[] args) throws Exception {  

4.      String uri = args[0];  

5.      Configuration conf = new Configuration();  

6.      FileSystem fs = FileSystem.get(URI.create(uri), conf);  

7.      FSDataInputStream in = null;  

8.      try {  

9.        in = fs.open(new Path(uri));  

10.       IOUtils.copyBytes(in, System.out, 4096, false);  

11.       in.seek(0); // go back to the start of the file  

12.       IOUtils.copyBytes(in, System.out, 4096, false);  

13.     } finally {  

14.       IOUtils.closeStream(in);  

15.     }  

16.   }  

17.

在一个小文件上运行得到以下结果:

1.      % hadoop FileSystemDoubleCat hdfs://localhost/user/tom/quangle.txt  

2.  On the top of the Crumpetty Tree  

3.  The Quangle Wangle sat,  

4.  But his face you could not see,  

5.  On account of his Beaver Hat.  

6.  On the top of the Crumpetty Tree  

7.  The Quangle Wangle sat,  

8.  But his face you could not see,  

9.  On account of his Beaver Hat. 

FSDataInputStream也实现了PositionedReadable接口,从一个指定位置读取一部分数据:

1.  public interface PositionedReadable {  

2.   

3.    public int read(long position, byte[] buffer, 
int offset, int length)  

4.          throws IOException;  

5.   

6.    public void readFully(long position, byte[] 
buffer, int offset, int length)  

7.          throws IOException;  

8.   

9.    public void readFully(long position, byte[] 
buffer) throws IOException;  

10.

read()方法从指定position读取指定长度的字节放入缓冲buffer的指定偏离量offset。返回值是实际读到的字节数:调用者需要检查这个值,它有可能小于指定的长度。readFully()方法会读出指定字节由length指定的数据到buffer中或在只接受buffer字节数组的版本中,再读取buffer.length字节(这儿指的是第三个函数),若已经到文件末,将会抛出EOFException

所有这些方法会保留文件当前位置并且是线程安全的,因此它们提供了在读取文件(可能是元数据)的主要部分时访问其他部分的便利方法。其实,这只是使用Seekable接口的实现,格式如下:

1.      long oldPos = getPos();  

2.  try {  

3.    seek(position);  

4.    // read data  

5.  } finally {  

6.    seek(oldPos);  

7. 

最后务必牢记,seek()是一个相对高开销的操作,需要慎重使用。我们需要依靠流数据构建应用访问模式(如使用MapReduce),而不要大量执行seek操作。

更多分享请关注:bbs.superwu.cn

超人学院
粉丝 116
博文 335
码字总数 388917
作品 0
昌平
CTO(技术副总裁)
私信 提问
加载中
请先登录后再评论。
HDFS的基本操作(增删查)

本片文章主要介绍利用FileSystem API对HDFS进行相关操作,如增删查等——HDFS不支持对文件在任意位置修改。 1 从HDFS中读取数据 从HDFS中读取数据,主要是从存放在HDFS中的文件中读取数据,可...

lu__peng
2018/01/05
0
0
HDFS的基本操作(增删查)

本片文章主要介绍利用FileSystem API对HDFS进行相关操作,如增删查等——HDFS不支持对文件在任意位置修改。 1 从HDFS中读取数据 从HDFS中读取数据,主要是从存放在HDFS中的文件中读取数据,可...

lu__peng
2018/01/05
0
0
Hadoop(五)搭建Hadoop客户端与Java访问HDFS集群

  上一篇详细介绍了HDFS集群,还有操作HDFS集群的一些命令,常用的命令: hdfs dfs -ls xxx   注意:这里要说明一下-cp,我们可以从本地文件拷贝到集群,集群拷贝到本地,集群拷贝到集群...

osc_7hoa7os1
2019/11/05
1
0
第4章 HDFS操作

[TOC] 4.1 命令行操作 可以通过命令行接口与HDFS系统进行交互,这样更加简单直观。下面就介绍一些HDFS系统的常用操作命令。 1.ls 使用ls命令可以查看HDFS系统中的目录和文件。例如,查看HDF...

osc_jor8x3el
2018/07/10
0
0
【HDFS】四、HDFS的java接口

  Hadoop是用java语言实现的,因此HDFS有很好的java接口用以编程,重点就是Hadoop的FileSystem类,它是所有文件系统的抽象类,HDFS实例(DistributedFileSystem)也是基于它实现的。本部分...

osc_bf1dhmmd
2019/06/21
3
0

没有更多内容

加载失败,请刷新页面

加载更多

要求jQuery在执行某些操作之前等待所有图像加载的官方方式

问题: In jQuery when you do this: 在jQuery中,当您执行以下操作时: $(function() { alert("DOM is loaded, but images not necessarily all loaded");}); It waits for the DOM t......

法国红酒甜
昨天
11
0
实现Map按值排序

Map按照值排序,需要自定义比较器,实现Comparator接口,实现compare方法。 public class SortByVlue {public static void main(String[] args) {Map<String, Long> map = new HashMap<......

游人未归
昨天
16
0
定天气爬虫加定时发送天气邮件

今天无聊,在家研究个爬虫玩玩 主要用到以下几个库: request 请求资源 iconv-lite转码,有的网站html格式不是utf-8 cheerio类似jq,操作html,获取相关爬虫数据 nodemailer 发送邮件,例如q...

莫西摩西
昨天
14
0
还在为大屏分辨率困扰?图扑提供响应式(自适应)可视化大屏

前言 数据可视化在当下信息时代已经成为炙手可热的话题,而 B/S 化趋势,也使得许多大屏应用上在网页端出现,今天给大家分享一套不一样风格的大屏页面,与传统深蓝色不同,这次采用了暗红色设...

xhload3d
昨天
30
0
如何妙用Spring 数据绑定机制

前言 在剖析完 Spring Boot 返回统一数据格式是怎样实现的?文章之后,一直觉得有必要说明一下 Spring's Data Binding Mechanism 「Spring 数据绑定机制」。 默认情况下,Spring 只知道如何转...

码农小胖哥
2019/12/27
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部