Hadoop中的FileSystem学习

要获取hdfs上的文件信息,有两种方法:

  1. 通过JDK的java.net.URL
    通过java.net.URL对象来打开一个欲从中读取数据的流(stream),在使用中这种方法时,需要为URL对象指定URLStreamHandlerFactory(),这样URL才能识别出hdfs://开头的标识。
    这个方法在每个JVM中只能调用一次,所以它通常会被放在一个static block中执行(如下所示),但如果你的某部分程序——例如一个你无法修改源代码的第三方组件——已经调用了这个方法,那你就不能通过URL来这样读取数据了(下一节我们会介绍另一种方法)。
    代码如下:
package com.hdfs.FileSyetem;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;

/**
 * 利用JDK的 java.net.URL对象来打开一个欲从中读取数据的流(stream)
 * @author hadoop
 *
 */
public class JavaUrl2Hdfs {
    static{
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }
    public static void main(String[] args) {
        String uri ="hdfs://hadoop01:9000/user/hive/warehouse/student/student.txt";
        InputStream in = null;
        try {
            in = new URL(uri).openStream();
            IOUtils.copyBytes(in, System.out, 4096, false);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            IOUtils.closeStream(in);
        }

    }

}
  1. 使用FileSystem读取数据
    就像上节所说的,有时候我们无法通过设置URLStreamHandlerFactory方法的方式来通过URL读取数据,这时FIleSystem API就派上用场了。
      Hadoop文件系统中的文件是用Hadoop的Path对象来表示的(而不是java中的java.io.File对象,因为它的语义太接近于本地文件系统了)。你可以把一个Path对象看做Hadoop文件系统中的某一个URL,如上例中的“hdfs://hadoop01:9000/user/hive/warehouse/student/student.txt”。
      Filesystem是一个通用的文件系统API,所以使用它的第一步就是先抽取出它的一个实例出来——在这个例子中是HDFS。下面列出了几个Filesystem的用于抽取Filesystem实例的几个静态方法:
      
public static FileSystem get(Configuration conf) throws IOException
public static FileSystem get(URI uri, Configuration conf) throws IOException
public static FileSystem get(URI uri, Configuration conf, String user) throws IOException

一个Configuration对象封装了客户端或服务器端的配置信息,这些配置信息是通过从conf/core-size.xml之类的配置文件中读取出来的名值对来设置的。下面我们一一说明上面的三个方法:
  1)第一个方法返回一个默认的文件系统(在conf/core-site.xml中通过fs.default.name来指定的,如果在conf/core-site.xml中没有设置则返回本地文件系统)。
  2)第二个方法通过uri来指定要返回的文件系统(例如,如果uri是上个测试例子中的hdfs://localhost/user/tom/quangle.txt,也即以hdfs标识开头,那么就返回一个hdfs文件系统,如果uri中没有相应的标识则返回本地文件系统)。
  3)第三个方法返回文件系统的机理同(2)是相同的,但它同时又限定了该文件系统的用户,这在安全方面是很重要的。
  有时候你可能想要使用一个本地文件系统,你可以使用另一个很方便的方法:
    public static LocalFileSystem getLocal(Configuration conf) throws IOException
  得到一个文件系统的实例后,我们可以调用该实例的open()方法来打开某个给定文件的输入流(第一个方法使用一个默认的4KB的输入缓冲):

public FSDataInputStream open(Path f) throws IOException
public abstract FSDataInputStream open(Path f, int bufferSize) throws IOExceptio

把上面介绍的组合起来我们就得到了下面的代码:

package com.hdfs.FileSyetem;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;


public class FileSystemCat {
    /**
     * 获取hdfs上的所有文件,以及文件夹
     * @param args
     * @throws IOException 
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws IOException, InterruptedException {
        String uri ="hdfs://hadoop01:9000/user/hive/warehouse/student/student.txt";
        Configuration conf = new Configuration();
          FileSystem fs = FileSystem.get(URI.create(uri), conf);
            InputStream in = null;
         try{
              in = fs.open(new Path(uri));
              IOUtils.copyBytes(in, System.out, 4096, false);
            } finally {
              IOUtils.closeStream(in);
            }
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值