使用者可以将其理解成一个文件系统,就是往里面放文件,取文件操作。
其有一个或者多个namenode,用来管理文件目录
有多个datanode用来存文件(相当于大硬盘),当datanode空间不够的时候,直接继续加datanode就可以扩展了(只要namenode的内存还能存得下目录结构)
hadoop集群默认使用linux的权限控制,windows或者java项目要操作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
此方法相当复杂,这里不研究。
这种方法安全性太低,不推荐使用
首先建立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文件系统:
我们先测试一下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"));*/
}
}
执行:报错:
提示为未知协议 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连接获取文件流
③处理获得的输入流,比如保存、获取数据、输出等
通过这三行代码:
//这是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);
}
}