一.概述
- 除了可以用HDFS shell的方式 来访问HDFS上的数据,Hadoop还提供了以Java API的方式来操作HDFS上的数据.由于我们实际开发的大数据应用都是以代码的方式提交的,所以在代码中使用API的方式来操作HDFS数据必须掌握
二.搭建环境
1.使用Maven构建Java程序,添加maven的依赖包
- 在pom.xml文件中的<dependencies>标签下添加如下代码:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
2.修改hdfs-site.ml文件,添加如下配置,放开权限,重启hdfs服务
<!-- 设置权限关闭,易于访问操作,否则可能因权限问题无法访问 -->
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
3.单元测试的setUp和tearDown方法
- 在单元测试中,一般将初始化的操作放在setUp方法中完成,将关闭资源的操作放在tearDown方法中完成,代码如下:
package hadoop.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.URI;
public class HDFSApp {
public static final String HDFS_PATH="hdfs://hadoop110:9000";
Configuration cfg=null;
FileSystem fs = null;
@Before
public void setUp() throws Exception{
System.out.println("HDFSApp.setUp()");
cfg = new Configuration();
fs= FileSystem.get(new URI(HDFS_PATH),cfg);
}
@After
public void tearDown() throws Exception{
cfg = null;
fs= null;
System.out.println("HDFSApp.tearDown()");
}
}
4.使用Java API操作HDFS的常用操作
1)创建目录
@Test
public void mkdir()throws Exception{
String path = "/hdfsapi/test";
fs.mkdirs(new Path(path));
System.out.println("目录创建成功");
}
- 执行效果如如下:
- 去50070端口查看是否创建成功:
- 如上图所示创建成功!
2)创建文件并写入数据
@Test
public void createFile()throws Exception{
String path = "/hdfsapi/test/a.txt";
FSDataOutputStream fsdos = fs.create(new Path(path));
fsdos.write("hello world,I am creating file and output data".getBytes());
fsdos.flush();
System.out.println("创建文件并写入数据成功!");
fsdos.close();
}
- 执行效果如下:
- 去hadoop环境下查看有没有该文件:
hdfs dfs -cat /hdfsapi/test/a.txt
,执行效果如下可知已创建文件并写入数据成功
3)重命名操作
@Test
public void rename() throws Exception{
Path oldPath = new Path("/hdfsapi/test/a.txt");
Path newPath = new Path("/hdfsapi/test/b.txt");
System.out.println(fs.rename(oldPath,newPath));
}
- 执行效果如下:
- 去50070端口查看是否改名了,如下已成功改名:
4)上传本地文件到HDFS
@Test
public void copyFromLocal() throws Exception{
Path src = new Path("copyFile");
Path dist = new Path("/hdfsapi/test/");
fs.copyFromLocalFile(src,dist);
System.out.println("上传成功");
}
- 执行效果如下:
- 去50070端口查看是否成功,如下:
5)查看某目录下的所有文件
@Test
public void listFiles() throws Exception{
FileStatus[] listStatus = fs.listStatus(new Path("/hdfsapi/test/"));
for (FileStatus status : listStatus) {
String isDir = status.isDirectory()?"文件夹":"文件";
String permission = status.getPermission().toString();
short replication = status.getReplication();
long len = status.getLen();
String path = status.getPath().toString();
System.out.println(isDir+"\t"+permission+"\t"+replication+"\t"+len+"\t"+path);
}
}
- 执行效果如下:
6)查看文件块信息
@Test
public void getFileBlock() throws Exception{
FileStatus fileStatus = fs.getFileStatus(new Path("/hdfsapi/test/b.txt"));
BlockLocation[] blocks=fs.getFileBlockLocations(fileStatus,0,fileStatus.getLen());
for (BlockLocation block : blocks) {
for (String host : block.getHosts()) {
System.out.println(host);
}
}
}
- 执行结果如下:
7)下载一个文件到本地
- 注意:下载时需要在windows系统上配置hadoop
- a.解压hadoop压缩文件到windows系统上
- b.在windows系统上配置hadoop的环境变量
- d.将以下文件拖入hadoop解压后目录的bin目录下,将hadoop.dll文件拖入系统盘的System32目录下(提取码: azpe)
点我获取
- c.修改windows系统的主机列表(添加虚拟机上的主机):
//下载一个文件到本地
@Test
public void testCopyToLocalFile() throws URISyntaxException, IOException, InterruptedException {
fs.copyToLocalFile(new Path("/user/java/copyFile"),new Path("F:\\sunyong\\Java\\codes\\javaToHdfs\\download\\copyFile2.txt"));
System.out.println("下载成功!");
}
- 执行效果如下
- 查看内容: