通过HDFS FileSystem API 对 HDFS 进行操作
windows下安装eclipse-hadoop插件
- 将hadoop-eclipse-plugin-2.6.0.jar复制到eclipse安装目录下的plugins文件夹中。
- 将hadoop.dll和winutils.exe复制到Windows的hadoop安装目录的bin文件夹下
- Windows解压hadoop2.7.3
- 配置环境变量:HADOOP_HOME = D:/hadoop2.7.3;
【配置PATH属性:%HADOOP_HOME%\bin;%HADOOP_HOME%\sbin】- eclipse–>[windows]–>[首选项]–>[hadoop MapReduce]
【设置hadoop的安装目录】
- 打开【Mapreduce Locations】视图窗口 --> 右键 --> 【new Hadoop location】
Location name:mumu #随意名字
Map/Redce(v2) Master
DFS Master
host:master host:master
port:9001 post:9000
User name:hadoop #集群用户名
- 打开Map/Reduce编程视图【集群开启就会自动连接】
右键 --> Reconnect
通过Java URL方式访问HDFS【成功】
【FromURLJHadoop.java】
package com.hyxy.hadoop.hdfs;
import java.io.InputStream;
import java.net.URL;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;
public class FromURLJHadoop {
static{
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
public static void main(String[] args) {
InputStream io = null;
try {
io = new URL("hdfs://master:9000/tree.txt").openStream();
IOUtils.copyBytes(io, System.out, 4096, false);
} catch (Exception e) {
e.printStackTrace();
}finally {
IOUtils.closeStream(io);
}
}
}
测试Java API 的 URL 对 HDFS 进行写操作【失败】
package com.hyxy.hadoop.hdfs;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
public class ToURLHadoop {
static {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
public static void main(String[] args) throws Exception {
OutputStream out = null;
try {
URLConnection conn = new URL("hdfs://master:9000/mumu/geek/tree.txt").openConnection();
out = conn.getOutputStream();
out.write("hello world".getBytes());
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
java.net.UnknownServiceException: protocol doesn’t support output
at java.net.URLConnection.getOutputStream(URLConnection.java:843)
at com.hyxy.hadoop.hdfs.ToURLHadoop.main(ToURLHadoop.java:19)
主要代码分析
【configuration只加载core-site.xml】
- 【org.apache.hadoop.conf.Configuration】类说明或作用:
- [Resource]:资源定义及加载
资源默认按顺序加载:core-site.xml --> core-site.xml --> 代码段
资源描述以name/value键值对定义。
- [Final Parameters]:不变参数
配置参数可以声明为final。一旦资源声明了一个值是final,以后加载的资源就不能更改该值
- [Variable Expansion]:参数表达式
值字符串首先处理变量展开
- Configuration用法:如果访问hdfs,在Java API 中需调用以下几种方式,来获取Resources
- 通过conf.set(“fs.defaultFS”, “hdfs://master:9000”);
- 通过conf.addResource(“core”); #将core-site.xml复制到classpath下,命名为core
- 将core-site.xml文件拷贝到classpath下,默认加载core-default.xml,然后加载core-site.xml中重写项
- 【写数据到HDFS中的文件中】【开启HDFS文件系统可以用FileSystem也可以用其实现类DistributedFileSystem】
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public class HDFSDemo {
public static void main(String[] args) {
readDataFromHDFS();
}
public static void readDataFromHDFS() {
Configuration conf = new Configuration();
System.out.println(conf.get("fs.defaultFS"));
//方式一、常用这种,这是具体的设置,集群使用默认的配置文件,但在具体的业务下,使用set是走代码,覆盖配置,但不会更改配置文件内容,就不会更改整个集群的配置
//conf.set("fs.defaultFS", "hdfs://master:9000");
//方式二、
//conf.addResource("core");
//方式三、将core-site.xml拷到src下,默认加载,常用这种
System.out.println(conf.get("fs.defaultFS"));
try {
FileSystem fs = FileSystem.get(conf);
Path file = new Path("hdfs://master:9000/Hello.java");
FSDataInputStream fsinput = fs.open(file);
IOUtils.copyBytes(fsinput, System.out, 4096, false);
fsinput.close();
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 默认情况下,先加载core-default.xml,然后加载core-site.xml
在【org.apache.hadoop.conf.Configuration】第649行,静态代码块中执行。 - FileSystem抽象类一般实现类为两类:【DistributedFileSystem】和【LocalFileSystem】
- 调整相关参数时,个别全局变量需在集群端修改,重启生效。
- 【创建目录】
- 修改根目录的权限
$>hadoop fs -chmod -R +w /
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
public class HDFSDemo2 {
public static void main(String[] args) {
mkdirByAPI();
}
public static void mkdirByAPI() {
Configuration conf = new Configuration();
try {
DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
//代码方式创建文件夹
dfs.mkdirs(new Path("/dir"));
dfs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 【获取文件或目录详情】
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
public class HDFSDemo3 {
public static void main(String[] args) {
getFileStatus();
}
public static void getFileStatus() {
Configuration conf = new Configuration();
try {
DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
//获取文件或目录的详情
FileStatus fst = dfs.getFileStatus(new Path("/Hello.java"));
System.out.println("getAccessTime:" + fst.getAccessTime());
System.out.println("getBlockSize:" + fst.getBlockSize());
System.out.println("getGroup:" + fst.getGroup());
System.out.println("getLen:" + fst.getLen());
System.out.println("getReplication:" + fst.getReplication());
System.out.println("getPermission:" + fst.getPermission());
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 【获取文件路径或目录子文件及子目录列表】
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
public class HDFSDemo4 {
public static void main(String[] args) {
getFileStatusArray();
}
public static void getFileStatusArray() {
Configuration conf = new Configuration();
try {
DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
//获取文件路径或目录子文件及子目录列表
FileStatus[] fst_arr = dfs.listStatus(new Path("/"));
Path[] path_arr = FileUtil.stat2Paths(fst_arr);
for(Path path : path_arr) {
System.out.println(path);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 【通过API进行写操作,覆盖操作】
- 可以指定副本数,块大小,但是块大小若小于默认最小值,则必须在集群中修改默认参数,并重启集群
- 同时还要设置校验和的大小,不过校验和可以在客户端修改
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
public class HDFSDemo5 {
//通过API进行写操作
public static void main(String[] args) {
writeByAPI();
}
public static void writeByAPI() {
Configuration conf = new Configuration();
//conf.set("dfs.namenode.fs-limits.min-block-size", "1");【客户端设置是无效的】
conf.set("dfs.bytes-per-checksum", "1");
try {
DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
Path file = new Path("hdfs://master:9000/test.java");
//FSDataOutputStream fsos = dfs.create(file);
FSDataOutputStream fsos = dfs.create(file, true, 4096, (short)2, 3);
fsos.writeBytes("Hello China!");
System.out.println("ok");
fsos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 【通过API进行写操作,追加操作】
- 必须打开yarn,否则报错
package com.hyxy.hadoop.hdfs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
public class HDFSDemo6 {
//通过API进行追加写操作
public static void main(String[] args) {
writeByAPI();
}
public static void writeByAPI() {
Configuration conf = new Configuration();
conf.set("dfs.bytes-per-checksum", "1");【必须写,因为test.java创建时,块大小设置为3】
【如果是其他文件,则不能修改校验和】
try {
DistributedFileSystem dfs = (DistributedFileSystem) FileSystem.get(conf);
Path file = new Path("hdfs://master:9000/test.java");
FSDataOutputStream fsos = dfs.append(file);
fsos.writeBytes("Hello China!");
System.out.println("ok");
fsos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}