hadoop2.7入门-java访问hdfs文件

hadoop2.7入门-java访问hfs文件

  • 1、hdfs文件存储系统
  • 2、解决hadoop集群的访问权限
    • 2.1、关闭hadoop权限检查
    • 2.2、使用kerberos进行权限配置
    • 2.3、把整个hadoop的目录的权限改成777
    • 2.4、在windows环境中添加系统环境变量hadoopUserName
  • 3、java访问hdfs
    • 3.1、使用URL获取文件流信息
    • 3.2、通过hdfs的FileSystem操作文件

1、hdfs文件存储系统

使用者可以将其理解成一个文件系统,就是往里面放文件,取文件操作。
其有一个或者多个namenode,用来管理文件目录
有多个datanode用来存文件(相当于大硬盘),当datanode空间不够的时候,直接继续加datanode就可以扩展了(只要namenode的内存还能存得下目录结构)

2、解决hadoop集群的访问权限

hadoop集群默认使用linux的权限控制,windows或者java项目要操作hadoop集群的文件,则需要先解决权限问题。
这里主要有三种解决方案:

2.1、关闭hadoop权限检查

如果是测试功能用的话,最简单的办法是关闭hadoop的权限检查
修改配置文件hdfs-site.xml,增加dfs.permissions.enabled,属性设置为false
vim /usr/local/hadoop-2.7.3/etc/hadoop/hdfs-site.xml
增加:

  <property>
    <name>dfs.permissions.enabled</name>
    <value>false</value>
  </property>

保存后,重启namenode
hadoop-daemon.sh stop namenode
hadoop-daemon.sh start namenode

2.2、使用kerberos进行权限配置

此方法相当复杂,这里不研究。

2.3、把整个hadoop的目录的权限改成777

这种方法安全性太低,不推荐使用

2.4、在windows环境中添加系统环境变量hadoopUserName

3、java访问hdfs

首先建立java项目,编译环境JDK1.8
如果是传统项目,则引入hadoop对应的jar包、hdfs对应的jar包
如果是maven项目,则增加以下依赖:

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.3</version>
        </dependency>

java基本环境准备好了,现在可以编写java程序来测试操作hdfs文件系统:

3.1、使用URL获取文件流信息

我们先测试一下URL的使用

package com.demo.hdfs;

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

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

public class HdfsTest {
    public static void main(String[] args) throws Exception{
        URL url = new URL("http://www.baidu.com");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);

        /*URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
        URL url = new URL("hdfs://192.168.13.135:9000/core-site.xml");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);

        Configuration config = new Configuration();
        config.set("fs.defaultFS","hdfs://192.168.13.135:9000");
        FileSystem fs = FileSystem.get(config);

        Boolean bl = fs.mkdirs(new Path("/test"));*/
    }
}

URL默认是http协议,直接可以访问http协议的地址;
如果我们直接访问hdfs文件系统,可以测试代码如下:

package com.demo.hdfs;

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

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

public class HdfsTest {
    public static void main(String[] args) throws Exception{
        /*URL url = new URL("http://www.baidu.com");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);*/

        /*URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
        */
         
        URL url = new URL("hdfs://192.168.13.135:9000/core-site.xml");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);

        /*Configuration config = new Configuration();
        config.set("fs.defaultFS","hdfs://192.168.13.135:9000");
        FileSystem fs = FileSystem.get(config);

        Boolean bl = fs.mkdirs(new Path("/test"));*/
    }
}

执行:报错:
hadoop2.7入门-java访问hdfs文件_第1张图片
提示为未知协议 hdfs,我们需要将hdfs的协议注册给URL才能识别,因此加上这一句:
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());

package com.demo.hdfs;

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

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

public class HdfsTest {
    public static void main(String[] args) throws Exception{
        /*URL url = new URL("http://www.baidu.com");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);*/

        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());

        URL url = new URL("hdfs://192.168.13.135:9000/core-site.xml");
        InputStream in = url.openStream();
        IOUtils.copyBytes(in, System.out, 4096, true);

        /*Configuration config = new Configuration();
        config.set("fs.defaultFS","hdfs://192.168.13.135:9000");
        FileSystem fs = FileSystem.get(config);

        Boolean bl = fs.mkdirs(new Path("/test"));*/
    }
}

URL方式访问获取文件流的方式完成了,主要步骤为
①注册hdfs协议名称
②普通连接URL方式创建URL连接获取文件流
③处理获得的输入流,比如保存、获取数据、输出等

3.2、通过hdfs的FileSystem操作文件

通过这三行代码:
//这是hdfs的配置类,可以添加配置信息
Configuration config = new Configuration();
config.set(“fs.defaultFS”,“hdfs://192.168.13.135:9000”);
FileSystem fs = FileSystem.get(config);
得到hdfs的文件系统对象。
该对象可以实现:创建目录、删除文件或目录、上传文件、获取文件、判断文件或者目录是否存在
例如:

package com.demo.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

import java.io.FileInputStream;
import java.io.InputStream;

public class HdfsTest {
    public static void main(String[] args) throws Exception{
        Configuration config = new Configuration();
        config.set("fs.defaultFS","hdfs://192.168.13.135:9000");
        FileSystem fs = FileSystem.get(config);

        Boolean bl = fs.mkdirs(new Path("/test"));
        System.out.println(bl);
        //创建目录/test2/test22,返回创建结果
        bl = fs.mkdirs(new Path("/test2/test22"));
        System.out.println(bl);
        //查看目录/test2是否存在
        bl = fs.exists(new Path("/test2"));
        System.out.println(bl);
        //上传,hdfs的目标位置
        FSDataOutputStream out = fs.create(new Path("/test2/testData.txt"));
        //上传,本地的文件
        InputStream in = new FileInputStream("D:\\worksoft\\Notepad++\\readme.txt");
        //IOUtils 可以实现上传或者下载,只要调整对应的输入和输出流即可
        IOUtils.copyBytes(in, out,4096, true);

        //列出/test2目录下的文件(夹)列表及状态
        FileStatus[] fileStatuses = fs.listStatus(new Path("/test2"));
        for (FileStatus fileStatus : fileStatuses) {
            //获取文件权限
            System.out.println(fileStatus.getPermission());
            //获取文件路径
            System.out.println(fileStatus.getPath());
            //获取文件的拷贝份数
            System.out.println(fileStatus.getReplication());
        }

        /*
         * 下载,获取对应的文件流,写入本地磁盘
         * 四个参数分别是:是否删除原文件、源文件地址、拷贝的目标文件地址、是否使用本地文件系统
        */
        fs.copyToLocalFile(false, new Path("/test2/testData.txt"), new Path("d:\\test.txt"),true);

    }
}

你可能感兴趣的:(linux,大数据,java技术积累)