1、获取指定目录下的全部文件及文件夹
/**
* 列出 {@param path} 下的文件和文件夹
*
* @param fs 文件系统实例
* @param path 路径
* @return 返回一个目录列表
* @throws IOException 对于任何IO错误
*/
public static List<String> listFileAndDir(FileSystem fs, Path path) throws IOException {
List<String> list = new ArrayList<>();
if (fs.exists(path)) {
FileStatus[] listStatus = fs.listStatus(path);
for (FileStatus status : listStatus) {
list.add(status.getPath().toString());
}
}
return list;
}
2、将本地文件拷贝到HDFS上
/**
* 将本地文件拷贝到hdfs上
*
* @param fs 文件系统实例
* @param delSrc 是否删除原文件
* @param src 原文件路径
* @param dst 目标文件路径
* @param overwrite 是否覆盖现有文件
* @throws IOException 对于任何IO错误
*/
public static void localCopyHDFS(FileSystem fs, boolean delSrc, boolean overwrite, Path src, Path dst) throws IOException {
fs.copyFromLocalFile(delSrc, overwrite, src, dst);
}
3、将HDFS上的文件拷贝到本地
/**
* 将HDFS上的文件拷贝到本地
*
* @param fs 文件系统实例
* @param delSrc 是否删除原文件
* @param src 原文件路径
* @param dst 目标文件路径
* @param useRawLocalFileSystem 是否进行文件校验,如果使用本地文件系统也就是设置为true,就不会产生crc校验,否则就会产生crc校验
* @throws IOException 对于任何IO错误
*/
public static void hdfsCopyLocal(FileSystem fs, boolean delSrc, Path src, Path dst, boolean useRawLocalFileSystem) throws IOException {
fs.copyToLocalFile(delSrc, src, dst, useRawLocalFileSystem);
}
4、对文件或文件夹重命名
/**
* 对文件或对文件夹重命名
*
* @param fs 文件系统实例
* @param src 要重命名的路径
* @param dst 重命名后的新路径
* @return true 重命名成功;false 重命名失败
* @throws IOException 对于任何IO错误
*/
public static boolean rename(FileSystem fs, Path src, Path dst) throws IOException {
return fs.rename(src, dst);
}
5、删除文件或文件夹
/**
* 删除文件或文件夹
*
* @param fs 文件系统实例
* @param src 要删除的路径
* @param recursive 如果是目录,设置为true,否则会抛出异常
* @return true 删除成功;false 删除失败
* @throws IOException 对于任何IO错误
*/
public static boolean deleteFile(FileSystem fs, Path src, boolean recursive) throws IOException {
return fs.delete(src, recursive);
}
6、判断是文件还是文件夹
/**
* 判断是文件还是文件夹
*
* @param fs 文件系统实例
* @param src 目标路径
* @return true 文件夹;false 文件
* @throws IOException 对于任何IO错误
*/
public static boolean isFileOrDir(FileSystem fs, Path src) throws IOException {
FileStatus[] status = fs.listStatus(src);
boolean flag = false;
for (FileStatus fileStatus : status) {
flag = fileStatus.isDirectory();
}
return flag;
}
7、查看文件详情
/**
* 查看文件详情
*
* @param fs 文件系统实例
* @param src 文件路径
* @param recursive 如果子目录需要递归遍历,设置为true
* @throws IOException 对于任何IO错误
*/
public static void fileDetails(FileSystem fs, Path src, boolean recursive) throws IOException {
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(src, recursive);
while (listFiles.hasNext()) {
LocatedFileStatus status = listFiles.next();
System.out.println("文件名:" + status.getPath().getName());
System.out.println("块大小:" + status.getBlockSize());
System.out.println("文件副本数:" + status.getReplication());
System.out.println("文件修改时间:" + status.getModificationTime());
System.out.println("文件所有者:" + status.getOwner());
System.out.println("文件所属组:" + status.getGroup());
System.out.println("文件大小:" + status.getLen());
// 块的位置
BlockLocation[] locations = status.getBlockLocations();
for (BlockLocation location : locations) {
// 块所在的主机 例如:hadoop51
String[] hosts = location.getHosts();
for (String host : hosts) {
System.out.println(host);
}
// 例如:192.168.0.51:9866
String[] names = location.getNames();
for (String name : names) {
System.out.println(name);
}
// 获取块的起始偏移量
System.out.println(location.getOffset());
// 获取块的长度
System.out.println(location.getLength());
// 获取块的每个副本的storageID。
// 例如:DS-5357e114-ccb7-46d5-994e-33c047853aa3
String[] storageIds = location.getStorageIds();
for (String storageId : storageIds) {
System.out.println(storageId);
}
// 获取块的每个副本的存储类型。
// 例如:DISK
// StorageType是一个枚举类型,还包括:RAM_DISK,SSD,ARCHIVE,PROVIDED
StorageType[] storageTypes = location.getStorageTypes();
for (StorageType storageType : storageTypes) {
System.out.println(storageType.name());
}
// 获取每个主机的网络拓扑路径列表。
// 例如:/default-rack/192.168.0.51:9866
String[] topologyPaths = location.getTopologyPaths();
for (String topologyPath : topologyPaths) {
System.out.println(topologyPath);
}
}
}
}
8、使用IOUtils工具类,将本地文件上传到HDFS
/**
* HDFS 文件上传
*
* @param fs 文件系统实例
* @param configuration 配置信息
* @param src 原文件路径
* @param dst 目标文件路径
* @throws IOException 对于任何IO错误
*/
public static void putFileToHDFS(FileSystem fs, Configuration configuration, File src, Path dst) throws IOException {
// 创建输入流
FileInputStream fis = new FileInputStream(src);
// 获取输出流
FSDataOutputStream fos = fs.create(dst);
// 流对拷
IOUtils.copyBytes(fis, fos, configuration);
// 关闭资源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
}
9、使用IOUtils工具类,将HDFS上的文件下载到本地
/**
* HDFS 文件下载
*
* @param fs 文件系统实例
* @param configuration 配置信息
* @param src 原文件路径
* @param dst 目标文件路径
* @throws IOException 对于任何IO错误
*/
public static void getFileFromHDFS(FileSystem fs, Configuration configuration, Path src, File dst) throws IOException {
// 获取输入流
FSDataInputStream fis = fs.open(src);
// 创建输出流
FileOutputStream fos = new FileOutputStream(dst);
// 流对拷
IOUtils.copyBytes(fis, fos, configuration);
// 关闭资源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
}
10、下载HDFS上指定文件的某一个block
/**
* 下载HDFS上指定文件的某一个block
* 验证需要在cmd命令下使用:type jdk-8u171-windows-x64.zip.part1 >> jdk-8u171-windows-x64.zip.part0, 最后把jdk-8u171-windows-x64.zip.part0重命名为jdk-8u171-windows-x64.zip
* @param fs 文件系统实例
* @param src 原文件路径
* @param block 要下载那一块,从0开始
* @param dst 目标文件路径
* @throws IOException IO 异常
*/
public static void readFileBlock(FileSystem fs, Path src, int block, File dst) throws IOException {
// 获取输入流
FSDataInputStream fis = fs.open(src);
// 指定块的起始位置和长度
long offset = 0; // 起始位置
long len = 0; // 长度
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(src, false);
while (listFiles.hasNext()) {
LocatedFileStatus status = listFiles.next();
// 获取文件的块位置
BlockLocation[] blockLocations = status.getBlockLocations();
for (int i = 0; i < blockLocations.length; i++) {
// 指定块
if (i == block) {
// 获取起始位置
offset = blockLocations[i].getOffset();
// 获取长度
len = blockLocations[i].getLength();
// 退出循环
break;
}
}
// 退出循环
break;
}
// 指定起始位置
fis.seek(offset);
// 创建输出流
FileOutputStream fos = new FileOutputStream(dst);
// 流对拷
byte[] buf = new byte[1024]; // 1k
// 这里的len / 1024 是因为buf定义了1k,相当于len乘以1024,假如len=134217728B=1024*1024*128,再乘以1024,就是len=137438953472B=1024*1024*1024*128=131072MB=128GB,所以要除掉
for (long i = 0; i < len / 1024; i++) {
fis.read(buf);
fos.write(buf);
}
// 关闭资源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
}
11、在main方法中调用
package com.hondali.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
public class HDFSApiOperation {
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
// 设置hadoop用户
System.setProperty("HADOOP_USER_NAME", "hadoop");
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop51:9000/"), configuration, "hadoop");
// 列出/test目录下的文件和文件夹
List<String> list = listFileAndDir(fs, new Path("/test"));
for (String ls : list) {
System.out.println(ls);
}
// 拷贝本地文件到hdfs
localCopyHDFS(fs, false, false, new Path("C:\\Users\\admin\\Desktop\\kaggle.txt"),new Path("/test"));
// 将hdfs上的文件拷贝到本地
hdfsCopyLocal(fs, false, new Path("/test/D43_DVT_LIMIT-7-31_20190802.csv"), new Path("C:\\Users\\admin\\Desktop\\D43_DVT_LIMIT-7-31_20190802.csv"),false);
// 重命名
System.out.println(rename(fs, new Path("/test1"), new Path("/test")) ? "重命名成功" : "重命名失败");
// 删除文件
System.out.println(deleteFile(fs, new Path("/test/kaggle.txt"), false) ? "删除成功" : "删除失败");
// 判断是文件还是文件夹
System.out.println(isFileOrDir(fs, new Path("/test")) ? "文件夹" : "文件");
// hdfs 上传文件
putFileToHDFS(fs, configuration, new File("C:\\Users\\admin\\Desktop\\jdk-8u171-windows-x64.zip"), new Path("/test/jdk-8u171-windows-x64.zip"));
// 文件详情
fileDetails(fs, new Path("/test/jdk-8u171-windows-x64.exe"), false);
// hdfs 文件下载
getFileFromHDFS(fs, configuration, new Path("/test/D43_DVT_LIMIT-7-31_20190802.csv"), new File("C:\\Users\\admin\\Desktop\\D43_DVT_LIMIT-7-31_20190802.csv"));
int block = 5;
readFileBlock(fs, new Path("/test/jdk-8u171-windows-x64.zip"), block, new File("C:\\Users\\admin\\Desktop\\jdk-8u171-windows-x64.zip.part" + block));
fs.close();
}
}