本篇博客記錄Java API操作HDFS過程
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.fs.permission.FsPermission;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
* Created by macan on 2017/1/14.
*
* hdfs Java API Operation
*/
public class HdfsConnection {
private FileSystem fs = null;
public HdfsConnection() throws URISyntaxException, IOException, InterruptedException {
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master1:9000");
fs = FileSystem.get(new URI("hdfs://master1:9000"), conf, "root");
}
/**
* 刪除HDFS 中指定的目錄
*
* @param path 需要刪除的目錄
* @param is 是否進行遞歸刪除文件
* @throws IOException
*/
public boolean delete(String path, boolean is) throws IOException {
boolean res = true;
if (exits(path)) {
res = fs.delete(new Path(path), is);
}
return res;
}
/**
* 查看文件是否存在
*
* @param path 文件路徑
* @return 如果文件存在,返回true,否則返回false
* @throws IOException
*/
public boolean exits(String path) throws IOException {
boolean res = fs.exists(new Path(path));
return res;
}
/**
* 創建一個文件
* @param path 文件的絕對路徑
* @param isOverride 如果文件已經存在,是否覆蓋創建是否覆蓋
* @return 返回寫文件流
* @throws IOException
*/
public FSDataOutputStream touch(String path, boolean isOverride) throws IOException {
if (exits(path)) {
return null;
}
return fs.create(new Path(path), isOverride);
}
/**
* 創建一個新的文件,並且寫入內容
* @param path 文件的絕對路徑
* @param isOverride 當文件已經存在的時候,是否覆蓋
* @param contex 寫入的內容
* @return 如果寫入成功,返回true,否則返回false
* @throws IOException
*/
public boolean touchAndWrite(String path ,boolean isOverride, String contex) throws IOException {
FSDataOutputStream outputStream = touch(path, isOverride);
if (outputStream == null){
return false;
}
outputStream.write(contex.getBytes(), 0, contex.length());
return true;
}
/**
* 創建目錄
* @param path 帶創建目錄的路徑
* @param model 權限
* @return 創建成功返回true 否則返回false
* @throws IOException
*/
public boolean mkdir(String path, String model) throws IOException {
if (exits(path)){
System.out.printf("path has been exited!");
return false;
}
FsPermission permission = new FsPermission(model);
return fs.mkdirs(new Path(path), permission);
}
/**
* 以默認全選創建目錄
* @param path 待創建文件的目錄
* @return 創建成功返回true,否則返回false
* @throws IOException
*/
public boolean mkdir(String path) throws IOException {
return mkdir(path, null);
}
/**
* 更改文件名
* @param path 文件所在路徑
* @param newName 新名字
* @param oldName 舊名
* @return
* @throws IOException
*/
public boolean rename(String path, String newName, String oldName) throws IOException {
if (!exits(path)){
System.out.println("file is not exits!");
return false;
}
fs.renameSnapshot(new Path(path), newName, oldName);
return true;
}
/**
* 根據新舊路徑進行更名
* @param oldPathName 原始文件路徑
* @param newPathName 現在文件路徑
* @return 成功返回true, 失敗返回false
* @throws IOException
*/
public boolean rename(String oldPathName, String newPathName) throws IOException {
if (!exits(oldPathName)){
System.out.println("file is not exits.");
return false;
}
fs.rename(new Path(oldPathName), new Path(newPathName));
return true;
}
/**
* 上傳文件到hdfs
* @param localPath 本地文件存儲路徑
* @param srcPath hdfs上路徑
* @return
*/
public boolean upload(String localPath, String srcPath){
try {
fs.copyFromLocalFile(new Path(localPath), new Path(srcPath));
} catch (IOException e) {
e.printStackTrace();
return false;
}finally {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
/**
* 下載hdfs文件到本地
* @param localPath 本地文件保存路徑
* @param srcPath hdfs上文件路徑路徑
* @return
*/
public boolean download(String localPath, String srcPath){
try {
fs.copyToLocalFile(new Path(srcPath), new Path(localPath));
} catch (IOException e) {
e.printStackTrace();
return false;
}finally {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
//讀取hdfs目錄上的文件
public FileStatus[] list(String path) throws IOException {
//獲取文件列表
return fs.listStatus(new Path(path));
}
/**
* 讀取指定hdfs目錄上所有文件,並打印在終端
* @param path 指定目錄
* @return
* @throws IOException
*/
public void listAndPrint(String path) throws IOException {
if (!exits(path)){
System.out.println("path not exits");
}
//獲取文件列表
FileStatus[] status = fs.listStatus(new Path(path));
for (int i = 0; i < status.length; ++i){
System.out.println(status[i].getPath().toString());
}
}
/**
* 通過流的方式,寫數據到HDFS
* @param frompath 本地文件路徑
* @param topath HDFS路徑
* @throws IOException
*/
public void uploadWithStream(String frompath, String topath) throws IOException {
//HDFS上的文件流
FSDataOutputStream outputStream = fs.create(new Path(topath), true);
//本地讀取的文件流
FileInputStream inputStream = new FileInputStream(frompath);
//將輸入文件流寫到輸出文件流
IOUtils.copy(inputStream, outputStream);
}
/**
* 通過流,將數據從HDFS中將數據寫到本地文件
* @param frompath HDFS路徑
* @param topath 本地路徑
* @throws IOException
*/
public void downloadWithStream(String frompath, String topath, int size)
throws IOException {
FSDataInputStream inputStream = fs.open(new Path(frompath), size);
FileOutputStream outputStream = new FileOutputStream(topath);
IOUtils.copy(inputStream, outputStream);
}
/**
* 通過指定偏移量,讀取HDFS中的文件
* @param frompath HDFS中的文件路徑
* @param topath 本地存放路徑
* @param offset 偏移量
* @throws IOException
*/
public void streamReadWithOffset(String frompath, String topath, int offset, int size)
throws IOException {
FSDataInputStream inputStream = fs.open(new Path(frompath), size);
inputStream.seek(offset);
FileOutputStream outputStream = new FileOutputStream(topath);
IOUtils.copy(inputStream, outputStream);
}
/**
* 獲取HDFS上的文件,輸出到終端
* @param frompath HDFS中的文件路徑
* @throws IOException
*/
public void streamPrintInTerminal(String frompath, int size) throws IOException {
FSDataInputStream inputStream = fs.open(new Path(frompath), size);
IOUtils.copy(inputStream, System.out);
}
}