本文列出了使用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;
}
}
}