一、回顾常用的命令
在上篇文章中整理了 HDFS 常用的命令,这里进行简单的回顾。
ls 命令用来查看 HDFS 系统中的目录和文件 ,命令如下:
$ hadoop fs -ls /
put 命令用来将本地文件上传到 hdfs 系统中 ,命令如下:
$ hadoop fs -put test.txt /
moveFromLocal 命令将本地文件移动到 HDFS 文件系统中,并将本地的文件进行删除 ,命令如下:
$ hadoop fs -moveFromLocal abc.txt /
get 命令用来将 HDFS 文件系统中的文件下载到本地 ,命令如下:
$ hadoop fs -get /abc.txt /home/hadoop/
rm 命令用来删除 HDFS 系统中的文件或文件夹 ,命令如下
$ hadoop fs -rm /test.txt
mkdir 命令用来在 HDFS 系统中创建目录 ,命令如下:
$ hadoop fs -mkdir /test
cp 命令在 HDFS 系统中用于文件的复制 ,命令如下:
$ hadoop fs -ls /
mv 命令在 HDFS 系统中用于完成文件移动的功能,也可以用来进行文件的重命名功能 ,命令如下:
mv /abc/abc.txt /test/ | hadoop fs -|
mv /test/abc.txt /test/abcabc.txt | hadoop fs -
cat 命令在 HDFS 文件系统中用于输出某个文件的内容 ,命令如下:
$ hadoop fs -cat /test/abcabc.txt
appendToFile 命令将单个或多个文件的内容从本地系统中追加到 HDFS 系统的文件中 ,命令如下:
$ hadoop fs -appendTo File abc.txt /abc.txt
上面的内容简单的对 HDFS 文件系统的常用命令进行了回顾,接下来,我们来整理一下关于 HDFS 常用的 Java API 。
二、引入依赖
使用 HDFS 的 Java API 可以操作 HDFS 文件系统中的文件,比如文件的新建、删除、读取等。创建一个 Maven 的项目,然后引入其依赖,准备工作就算是完成了,依赖如下:
<dependency> | |
<groupId>org.apache.hadoop</groupId> | |
<artifactId>hadoop-client</artifactId> | |
<version>.8.2</version> | |
</dependency> |
引入该依赖后,在 HDFS 的 Java API 中使用 FileSystem 工具类,它可以完成我们的操作,下面我们来进行了解。
三、文件列表
代码非常的简单,因此这里直接上代码,代码如下:
public static void main(String[] args) throws IO Exception { | |
Configuration conf = new Configuration(); | |
// 设置 HDFS 访问地址 | |
conf.set("fs.default.name", "hdfs:// centos 01:9000"); | |
// 取得 FileSystem 文件系统实例 | |
FileSystem fs = FileSystem.get(conf); | |
List<String> filesUnderFolder = HdfsFileSystem.getFileList(fs, new Path("hdfs:/")); | |
filesUnderFolder.forEach(System.out::println); | |
} | |
public static List<String> getFileList(FileSystem fs, Path folderPath) throws IOException { | |
List<String> paths = new ArrayList(); | |
if (fs. exists (folderPath)) { | |
FileStatus[] fileStatus = fs.listStatus(folderPath); | |
for (int i =; i < fileStatus.length; i++) { | |
FileStatus fileStatu = fileStatus[i]; | |
paths.add(fileStatu.getPath().toString()); | |
} | |
} | |
return paths; | |
} |
上面的代码中,在自定义的方法 getFileList 中通过 FileSystem 类的 listStatus() 方法返回了 HDFS 文件系统 / 目录下的所有文件和目录,输出内容如下:
hdfs://centos:9000/abc | |
hdfs://centos:9000/abc.txt | |
hdfs://centos:9000/depInput | |
hdfs://centos:9000/depOutput | |
hdfs://centos:9000/input | |
hdfs://centos:9000/output | |
hdfs://centos:9000/scoreInput | |
hdfs://centos:9000/scoreOutput | |
hdfs://centos:9000/secondInput | |
hdfs://centos:9000/secondOutput | |
hdfs://centos:9000/test | |
hdfs://centos:9000/tmp |
上面的输出则是我 虚拟机 中 HDFS 中的文件列表。如果需要显示其他目录下的文件和目录列表,只需要传入相应的路径即可。如果要显示全部文件,只需要判断是否为目录,如果为目录直接递归调用就可以了。
四、创建目录
创建目录使用 FileSystem 类的 mkdirs 方法即可完成,代码如下:
public static void main(String[] args) throws IO Exception { | |
String path = "hdfs:/hdfsDir"; | |
HdfsFileSystem.createDir(path); | |
} | |
/** | |
* 创建 HDFS 目录 mydir | |
*/public static void createDir(String pathString) throws IOException { | |
Configuration conf = new Configuration(); | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
org.apache.hadoop.fs.FileSystem fs = org.apache.hadoop.fs.FileSystem.get(conf); | |
// 创建目录 | |
boolean created = fs.mkdirs(new Path(pathString)); | |
if (created) { | |
System.out.println("创建目录成功"); | |
} else { | |
System.out.println("创建目录失败"); | |
} | |
fs.close(); | |
} |
mkdirs 方法的返回类型是 boolean 类型,返回 true 表示创建成功,返回 false 表示创建失败。使用 HDFS 的命令来进行查看,命令如下:
$ hadoop fs -ls / | grep hdfsDir | |
drwxr-xr-x - Administrator supergroup 2021-11-12 10:09 /hdfsDir |
可以看到,/hdfsDir 目录被创建成功。
五、文件的创建
文件的创建使用 FileSystem 类的 create 方法即可完成文件的创建,代码如下:
public static void main(String[] args) throws IOException { | |
String path = "hdfs:/fileAbc.txt"; | |
String context = "1234"; | |
HdfsFileSystem.createFile(path, context); | |
} | |
/** | |
* 定义创建文件方法 | |
*/public static void createFile(String pathString, String context) throws IOException { | |
Configuration conf = new Configuration(); | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
FileSystem fs = FileSystem.get(conf); | |
// 打开一个输出流 | |
FSDataOutputStream outputStream = fs.create(new Path(pathString)); | |
// 写入文件内容 | |
outputStream.write(context.getBytes()); | |
outputStream.close(); | |
fs.close(); | |
System.out.println("文件创建成功"); | |
} |
上面的代码在 HDFS 的根目录下创建了一个名为 fileAbc.txt 的文件,并向文件内写入了 1234 这样的内容,通过命令来查看该文件是否创建成功,内容是否写入成功,命令如下:
ls / | grep fileAbc | hadoop fs -|
-rw-r--r-- Administrator supergroup 4 2021-11-12 10:17 /fileAbc.txt | |
cat /fileAbc.txt | hadoop fs -
六、文件内容的输出
文件内容的输出使用 FileSystem 类的 open 方法,使用输入流进行读取即可 。代码如下:
public static void main(String[] args) throws IOException { | |
String path = "hdfs:/fileAbc.txt"; | |
HdfsFileSystem.fileSystemCat(path); | |
} | |
/** | |
* 查询 HDFS 文件内容并输出 | |
*/public static void fileSystemCat(String pathString) throws IOException { | |
Configuration conf = new Configuration(); | |
// 设置 HDFS 访问地址 | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
// 取得 FileSystem 文件系统实例 | |
FileSystem fs = FileSystem.get(conf); | |
// 打开文件输入流 | |
InputStream in = fs.open(new Path(pathString)); | |
// 输出文件内容 | |
IOUtils. copy Bytes(in, System.out, 4096, false); | |
// 关闭输入流 | |
IOUtils.closeStream(in); | |
} |
运行代码即可看到文件的内容被输出,输出如下:
七、删除文件
文件的删除使用 FileSystem 类的 deleteOnExit 方法,代码如下:
public static void main(String[] args) throws IOException { | |
String path = "hdfs:/fileAbc.txt"; | |
HdfsFileSystem.deleteFile(path); | |
} | |
/** | |
* 删除文件 | |
*/public static void deleteFile(String pathString) throws IOException { | |
Configuration conf = new Configuration(); | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
FileSystem fs = FileSystem.get(conf); | |
Path path = new Path(pathString); | |
// 删除文件 | |
boolean isok = fs.deleteOnExit(path); | |
if (isok) { | |
System.out.println("删除成功"); | |
} else { | |
System.out.println("删除失败"); | |
} | |
fs.close(); | |
} |
通过命令进行查看,文件已经被删除了。
八、读取文件/目录的元数据
读取文件/目录的元数据使用 FileSystem 类的 getFileStatus 方法即可完成,代码如下:
public static void main(String[] args) throws IOException { | |
String path = "hdfs:/fileAbc.txt"; | |
String context = ""; | |
HdfsFileSystem.createFile(path, context); | |
HdfsFileSystem.fileStatusCat(path); | |
} | |
/** | |
* 获取文件或目录的元数据信息 | |
*/public static void fileStatusCat(String pathString) throws IOException { | |
// 创建 Configuration 对象 | |
Configuration conf = new Configuration(); | |
// 设置 HDFS 访问地址 | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
// 取得 FileSystem 文件系统实例 | |
FileSystem fs = FileSystem.get(conf); | |
FileStatus fileStatus = fs.getFileStatus(new Path(pathString)); | |
// 判断是文件夹还是文件 | |
if (fileStatus.isDirectory()) { | |
System.out.println("这是一个文件夹"); | |
} else { | |
System.out.println("这是一个文件"); | |
} | |
// 输出元数据信息 | |
System.out.println("文件路径:" + fileStatus.getPath()); | |
System.out.println("文件修改日期:" + new Timestamp(fileStatus.getModificationTime()).toString()); | |
System.out.println("文件上次访问日期:" + new Timestamp(fileStatus.getAccessTime()).toString()); | |
System.out.println("文件长度:" + fileStatus.getLen()); | |
System.out.println("文件备份数:" + fileStatus.getReplication()); | |
System.out.println("文件块大小:" + fileStatus.getBlockSize()); | |
System.out.println("文件所有者:" + fileStatus.getOwner()); | |
System.out.println("文件所在分组:" + fileStatus.getGroup()); | |
System.out.println("文件的权限:" + fileStatus.getPermission().toString()); | |
} |
通过 FileStatus 可以得到文件的各种信息,上面的输出内容如下:
这是一个文件 | |
文件路径:hdfs://centos:9000/fileAbc.txt | |
文件修改日期:-11-12 11:02:12.797 | |
文件上次访问日期:-11-12 11:02:12.438 | |
文件长度: | |
文件备份数: | |
文件块大小: | |
文件所有者:Administrator | |
文件所在分组:supergroup | |
文件的权限:rw-r--r-- |
这里,我们获取了文件的路径、修改日期、上次访问日期、文件长度等信息。
九、上传本地文件到 HDFS
上传文件使用 FileSystem 类的 copyFromLocalFile 即可完成,代码如下:
public static void main(String[] args) throws IOException { | |
HdfsFileSystem.uploadFileToHDFS("d:/mysql.docx", "hdfs:/"); | |
} | |
/** | |
* 上传本地文件到 HDFS | |
*/public static void uploadFileToHDFS(String srcPath, String dstPath) throws IOException { | |
// 创建配置器 | |
Configuration conf = new Configuration(); | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
// 取得 FileSystem 文件系统实例 | |
FileSystem fs = FileSystem.get(conf); | |
// 创建可供 hadoop 使用的文件系统路径 | |
// 本地目录/文件 | |
Path src = new Path(srcPath); | |
// HDFS 目录/文件 | |
Path dst = new Path(dstPath); | |
// 复制上传文帝文件至 HDFS 文件系统中 | |
fs.copyFromLocalFile(src, dst); | |
System.out.println("文件上传成功"); | |
} |
通过命令来查看上传的情况,命令如下:
$ hadoop fs -ls / | grep mysql | |
-rw-r--r-- Administrator supergroup 1470046 2021-11-12 11:06 /mysql.docx |
十、下载 HDFS 文件到本地
下载 HDFS 文件到本地使用 FileSystem 类的 copyToLocalFile 方法即可,代码如下:
public static void main(String[] args) throws IOException { | |
HdfsFileSystem.downloadFileToLocal("hdfs:/mysql.docx", "d:/test.docx"); | |
} | |
/** | |
* 下载文件到本地 | |
*/public static void downloadFileToLocal(String srcPath, String dstPath) throws IOException { | |
// 创建配置器 | |
Configuration conf = new Configuration(); | |
conf.set("fs.default.name", "hdfs://centos:9000"); | |
// 取得 FileSystem 文件系统实例 | |
FileSystem fs = FileSystem.get(conf); | |
// 创建可供 hadoop 使用的文件系统路径 | |
Path src = new Path(srcPath); | |
Path dst = new Path(dstPath); | |
// 从 HDFS 文件系统中复制下载文件至本地 | |
fs.copyToLocalFile(false, src, dst, true); | |
System.out.println("文件下载成功"); | |
} |
到本地的 D 盘进行查看,文件已经下载成功。
十一、总结
HDFS 是 Hadoop 项目中的核心模块,使用 HDFS 的 Java API 操作 HDFS 非常的方便也比较简单。 不知道大家注意到了么,HDFS 作为文件系统,它可以完成对 文件的 增加、追加、删除、查看 等功能,但是,竟然没有对文件进行修改的功能。这是 HDFS 有别于其他文件系统的一个特点,HDFS 的作者是出于什么样的目的如此设计呢?留着以后讨论吧!