本文列出了使用Java代码通过Hadoop FileSystem API对文件存储 HDFS 版文件系统进行常用操作的示例,您可以参考这些示例代码开发您的应用。
前提条件
已开通文件存储 HDFS 版服务并创建文件系统实例和挂载点。具体操作,请参见文件存储HDFS版快速入门。
已安装JDK,且JDK版本不低于1.8。
已安装文件存储 HDFS 版文件系统SDK。具体操作,请参见安装文件系统SDK。
背景信息
文件存储 HDFS 版通过文件系统SDK提供对Hadoop FileSystem API的兼容。更多信息,请参见Hadoop FileSystem API。
目前,部分Hadoop FileSystem API的兼容还未在文件存储 HDFS 版文件系统SDK中提供。更多信息,请参见使用限制。
安装Maven依赖
您的应用需要在Maven项目中加入以下依赖项才能操作文件存储 HDFS 版文件系统。
如果您已参考安装文件系统SDK将文件存储 HDFS 版文件系统SDK部署到应用的依赖环境中,则不需要将下面依赖打包到您的应用中。
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<!-- Hadoop版本建议不低于 2.7.2 -->
<version>2.7.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aliyun.dfs/aliyun-sdk-dfs -->
<dependency>
<groupId>com.aliyun.dfs</groupId>
<artifactId>aliyun-sdk-dfs</artifactId>
<!-- 建议使用最新版SDK -->
<version>1.0.5</version>
</dependency>
</dependencies>
应用初始化
在使用Hadoop FileSystem API访问文件存储 HDFS 版文件系统之前,需要先确保已加载文件存储 HDFS 版相关的配置,然后再实例化FileSystem。
初始化代码样例如下。
已配置core-site.xml文件,使用以下代码进行初始化操作。
private void init() throws IOException { conf = new Configuration(); //从指定的core-site.xml文件中读取配置 conf.addResource(new Path(PATH_TO_CORE_SITE_XML)); fileSystem = FileSystem.get(conf); }
未配置core-site.xml文件,使用以下代码加载文件存储 HDFS 版相关配置进行初始化操作。
private void init() throws IOException { conf = new Configuration(); //请将MountpointDomainName替换为您的文件存储HDFS版文件系统的挂载地址。例如,xxxx.cn-hangzhou.dfs.aliyuncs.com conf.set("fs.defaultFS", "dfs://DfsMountpointDomainName:10290"); conf.set("fs.dfs.impl", "com.alibaba.dfs.DistributedFileSystem"); conf.set("fs.AbstractFileSystem.dfs.impl", "com.alibaba.dfs.DFS"); fileSystem = FileSystem.get(conf); }
创建目录
调用FileSystem实例的exists方法判断该目录是否已经存在:
如果存在,则直接返回。
如果不存在,则调用FileSystem实例的mkdirs方法创建该目录。
创建目录代码样例如下。
/**
* 创建目录
*
* @param dirPath
* @return
* @throws IOException
*/
private boolean createDir(final Path dirPath) throws IOException {
if (!fileSystem.exists(dirPath)) {
return fileSystem.mkdirs(dirPath);
}
return true;
}
移动或者重命名
对于文件存储 HDFS 版来说,文件的重命名和移动是一个操作。调用FileSystem实例的rename方法对文件存储 HDFS 版文件系统的文件或目录进行重命名操作。
移动或重命名代码样例如下。
/**
* 移动或重命名
*
* @param srcPath
* @param destPath
* @return
* @throws IOException
*/
private boolean moveOrRename(final Path srcPath, final Path destPath) throws IOException {
return fileSystem.rename(srcPath, destPath);
}
删除文件或目录
通过调用FileSystem实例的exists方法判断该目录是否已经存在:
如果存在,则调用FileSystem实例的delete方法删除该路径。
如果不存在,则返回false。
删除文件或目录代码样例如下。
/**
* 删除文件或目录
*
* @param targetPath
* @return
* @throws IOException
*/
private boolean deletePath(final Path targetPath, boolean recursive) throws IOException {
if (!fileSystem.exists(targetPath)) {
return false;
}
return fileSystem.delete(targetPath, recursive);
}
上传文件
通过调用FileSystem实例的copyFromLocalFile方法,将文件从本地文件系统上传到文件存储 HDFS 版。
上传文件代码样例如下。
/**
* 上传文件
*
* @param localFilePath
* @param destFilePath
* @throws IOException
*/
private void uploadFile(final Path localFilePath, final Path destFilePath, boolean overwrite) throws IOException {
fileSystem.copyFromLocalFile(false, overwrite, localFilePath, destFilePath);
}
下载文件
通过调用FileSystem实例的copyToLocalFile方法,将文件从文件存储 HDFS 版下载到本地文件系统。
下载文件代码样例如下。
/**
* 下载文件
*
* @param srcFilePath
* @param localFilePath
* @throws IOException
*/
private void downloadFile(final Path srcFilePath, final Path localFilePath) throws IOException {
fileSystem.copyToLocalFile(srcFilePath, localFilePath);
}
获取文件或目录信息
通过调用FileSystem实例的listStatus方法获取文件或目录的信息。
获取文件或目录信息代码样例如下。
/**
* 获取文件或目录信息
*
* @param targetPath
* @throws IOException
*/
private void printStatus(final Path targetPath) throws IOException {
FileStatus[] fileStatuses = fileSystem.listStatus(targetPath);
System.out.println("# hadoop fs -ls " + targetPath.toString());
for (FileStatus fileStatus : fileStatuses) {
System.out.print(fileStatus.getPermission() + "\t");
System.out.print(fileStatus.getOwner() + "\t");
System.out.print(fileStatus.getGroup() + "\t");
System.out.print(fileStatus.getAccessTime() + "\t");
System.out.print(fileStatus.getPath() + "\n");
}
System.out.println("");
}
创建及写入文件
通过调用FileSystem实例的create方法获取写文件的输出流,然后对这个输出流进行写入。
创建及写入文件代码样例如下。
/**
* 创建及写入文件
*
* @param filePath
* @param content
* @throws IOException
*/
private void writeFile(final Path filePath, final String content) throws IOException {
try (FSDataOutputStream out = fileSystem.create(filePath)) {
out.write(content.getBytes());
out.hsync();
}
}
读文件
读文件即为获取文件存储 HDFS 版上某个指定文件的内容。通过调用FileSystem实例的open方法获取读文件的输入流,然后使用该输入流读取文件存储 HDFS 版的指定文件的内容。
读文件代码样例如下。
/**
* 读文件
*
* @param filePath
* @return
* @throws IOException
*/
private StringBuffer readFile(final Path filePath) throws IOException {
StringBuffer strBuffer = new StringBuffer();
try (FSDataInputStream in = fileSystem.open(filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String tempOneLine;
while ((tempOneLine = reader.readLine()) != null) {
strBuffer.append(tempOneLine);
}
return strBuffer;
}
}
}