大数据学习04_Hadoop: HDFS操作
HDFS操作
HDFS的Shell操作
- 基本语法
或bin/hadoop fs 具体命令
其中bin/hdfs dfs 具体命令
dfs
是fs
的实现类
HDFS常用命令
- 启动Hadoop集群
sbin/start-dfs.sh sbin/start-yarn.sh
-help
: 输出这个命令参数hadoop fs -help rm
-ls
: 显示目录信息hadoop fs -ls /
-mkdir
: 在HDFS上创建目录hadoop fs -mkdir -p /dir0/dir1
-moveFromLocal
: 从本地剪切粘贴到HDFShadoop fs -moveFromLocal ./myfile.txt /dir0/dir1
-appendToFile
: 追加一个文件到已经存在的文件末尾hadoop fs -appendToFile ./myfile.txt /dir0/dir1
-cat
: 显示文件内容hadoop fs -cat /dir0/dir1/myfile.txt
-chgrp
,-chmod
,-chown
: Linux文件系统中的用法一样,修改文件所属权限hadoop fs -chmod 666 /dir0/dir1/myfile.txt hadoop fs -chown myuser:mygroup /dir0/dir1/myfile.txt
-copyFromLocal
: 从本地文件系统中拷贝文件到HDFS路径去hadoop fs -copyFromLocal ./myfile.txt /dir0/dir1
-copyToLocal
: 从HDFS拷贝到本地hadoop fs -copyToLocal /dir0/dir1/myfile.txt ./
-cp
: 从HDFS的一个路径拷贝到HDFS的另一个路径hadoop fs -cp /dir0/dir1/myfile.txt /dir2
-mv
: 在HDFS目录中移动文件hadoop fs -mv /dir0/dir1/myfile.txt /dir2
-get
: 等同于copyToLocal,就是从HDFS下载文件到本地hadoop fs -get /dir0/dir1/myfile.txt ./
-getmerge
: 合并下载多个文件,用于将文档合并下载hadoop fs -getmerge /logs/* ./logs.txt
-put
: 等同于-copyFromLocal
:hadoop fs -put ./myfile.txt /dir0/dir1
-tail
: 显示一个文件的末尾hadoop fs -tail /dir0/dir1/myfile.txt
-rm
: 删除文件或文件夹hadoop fs -rm /dir0/dir1/myfile.txt
-rmdir
: 删除空目录hadoop fs -mkdir /emptydirectory
-du
: 统计文件夹的大小信息hadoop fs -du -s -h /dir0/dir1/myfile.txt
-setrep
: 设置HDFS中文件的副本数量hadoop fs -setrep 10 /dir0/dir1/myfile.txt
HDFS客户端操作
HDFS客户端环境准备
- 将
hadoop
的jar包拷贝到非中文,无空格的路径之下,如D:\Develop\hadoop-2.7.2
.并新建环境变量HADOOP_HOME
,其值为hadoop
的jar包路径. - 将
%HADOOP_HOME%/bin
和%JAVA_HOME%/bin
加入到环境变量Path
中. - 新建一个
Maven
工程HDFSClientDemo
,在工程下的pom.xml
中配置依赖如下:<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.7.7</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.7</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.7.7</version> </dependency> <!-- 若JDK版本高于1.8,则不存在tools.jar包,可以不用配置下边依赖 --> <dependency> <groupId>jdk.tools</groupId> <artifactId>jdk.tools</artifactId> <version>1.8</version> <scope>system</scope> <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath> </dependency> </dependencies>
- 在
src/main/java
中创建包cn.maoritian.hdfs
,在该包下创建类HdfsClient
如下:
执行上边程序,在package cn.maoritian.hdfs; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; public class HdfsClient { public static void main(String[] args) throws Exception { // 1 获取文件系统操作对象 // Configuration configuration = new Configuration(); // configuration.set("fs.defaultFS", "hdfs://hadoop102:9000"); // 第一个参数指定NameNode的位置 // 第二个参数创建参数对象 // 第三个参数指定登录的用户名 FileSystem fs = FileSystem.get(new URI("hdfs://192.168.111.102:9000"), new Configuration(), "root"); // 2 创建目录 fs.mkdirs(new Path("/dir1/dir2")); // 3 关闭资源 fs.close(); } }
http://hadoop102:50070/
中看到HDFS文件系统上创建了新目录/dir1/dir2
,证明客户端准备成功
HDFS的API操作
-
文件上传
@Test public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException { // 1. 获取文件系统操作对象 Configuration configuration = new Configuration(); configuration.set("dfs.replication", "2"); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root"); // 2. 上传文件 fs.copyFromLocalFile(new Path("D:/myfile.txt"), new Path("/dir1/myfile.txt")); // 3. 关闭资源 fs.close(); }
可以在
http://hadoop102:50070/
中看到上传文件的备份数为2,说明在程序中的优先级高于配置中的优先级. -
文件下载
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException { // 1 获取文件系统操作对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root"); // 2. 执行下载操作,参数如下 // boolean delSrc 是否将原文件删除 // Path src 要下载的文件路径 // Path dst 将文件下载到的路径 // boolean useRawLocalFileSystem 是否开启文件校验 fs.copyToLocalFile(false, new Path("/dir1/myfile.txt"), new Path("e:/myfile.txt"), true); // 3. 关闭资源 fs.close(); }
-
删除文件或目录
@Test public void testDelete() throws IOException, InterruptedException, URISyntaxException { // 1. 获取文件系统操作对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root"); // 2. 执行删除 // 第二个参数: boolean recursive 表示是否递归删除(针对目录) fs.delete(new Path("/dir1"), true); // 3. 关闭资源 fs.close(); }
-
文件名更改
@Test public void testRename() throws IOException, InterruptedException, URISyntaxException { // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root"); // 2 修改文件名称 fs.rename(new Path("/myfile1.txt"), new Path("/myfile2.txt")); // 3 关闭资源 fs.close(); }
-
文件详情查看
查看文件名称、权限、长度、块信息@Test public void testListFiles() throws IOException, InterruptedException, URISyntaxException { // 1. 获取文件系统操作对象 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root"); // 2 获取文件详情 RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true); // 迭代获取每个文件 while (listFiles.hasNext()) { LocatedFileStatus status = listFiles.next(); System.out.println(status.getPath().getName()); // 文件名称 System.out.println(status.getLen()); // 长度 System.out.println(status.getPermission()); // 权限 System.out.println(status.getGroup()); // 分组 // 获取存储的块信息 BlockLocation[] blockLocations = status.getBlockLocations(); // 遍历所有块 for (BlockLocation blockLocation : blockLocations) { // 获取块存储的主机节点 String[] hosts = blockLocation.getHosts(); for (String host : hosts) { System.out.println(host); } } System.out.println("-----------分割线----------"); } // 3 关闭资源 fs.close(); }
-
文件和文件夹判断
@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException {
// 1 获取文件系统操作对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root");
// 2 判断是文件还是目录
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
if (fileStatus.isFile()) {
// 是文件
System.out.println("f:" + fileStatus.getPath().getName());
} else {
// 是目录
System.out.println("d:" + fileStatus.getPath().getName());
}
}
// 3 关闭资源
fs.close();
}
HDFS的I/O流操作
将HDFS的I/O操作封装在I/O流中
// 文件上传
@Test
public void putFileToHDFS(String srcPath, String destPath) throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统操作对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root");
// 2. 创建输入流
FileInputStream fis = new FileInputStream(new File(srcPath));
// 3. 获取输出流
FSDataOutputStream fos = fs.create(new Path(destPath));
// 4. 流对拷
IOUtils.copyBytes(fis, fos, configuration);
// 5 关闭资源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
fs.close();
}
// 文件下载
@Test
public void getFileFromHDFS(String srcPath, String destPath) throws IOException, InterruptedException, URISyntaxException {
// 1. 获取文件系统操作对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "root");
// 2. 获取输入流
FSDataInputStream fis = fs.open(new Path(srcPath));
// 3. 获取输出流
FileOutputStream fos = new FileOutputStream(new File(destPath));
// 4 流的对拷
IOUtils.copyBytes(fis, fos, configuration);
// 5 关闭资源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
fs.close();
}