HDFS设计的主要目的是对海量数据进行存储,也就是说在其上能够存储很大量文件(可以存储TB级的文件)。HDFS将这些文件分割之后,存储在不同的DataNode上, HDFS 提供了两种访问接口:Shell接口和Java API 接口,对HDFS里面的文件进行操作,具体每个Block放在哪台DataNode上面,对于开发者来说是透明的。
通过Java API接口对HDFS进行操作,我将其整理成工具类,地址见底部
链接:https://www.cnblogs.com/codeOfLife/p/5396624.html(这位仁兄写的也不错)
1.首先我们需要一个工具类;
package com.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocalFileSystem;
import java.io.IOException;
/**
* Created by Administrator on 2019/4/23.
*/
public class Utils {
public static FileSystem getFs() throws IOException {
//通过配置类进行了链接
Configuration conf = new Configuration();
//找到Hadoop的最核心的配置文件
conf.set("fs.defaultFS","192.168.137.198:9000");
FileSystem fileSystem= FileSystem.get(conf);
return fileSystem;
}
public static LocalFileSystem getLocalFs() throws IOException {
Configuration conf = new Configuration();
LocalFileSystem localfs = LocalFileSystem.newInstanceLocal(conf);
return localfs;
}
}
2.接下来就是各种花式操作(操作过程中会有很多bug ,不过都说明了)
package com.hdfs;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.io.IOUtils;
import java.io.*;
/**
* Created by Administrator on 2019/4/23.
*/
public class HdfsOperation {
public static void main(String[] args) throws IOException {
//clusterStatus();
// fileStatus();
// renameOrMove();
dirOperation();
// deleteDir();
// isExist();
// createFile();
// readFile();
//upload();
// download();
}
//1、获取集群状态信息
public static void clusterStatus() throws IOException {
//root权限 需要到hdfs-site.xml文件配置
//System.setProperty("HADOOP_USER_NAME","root");
//链接
FileSystem fileSystem =Utils.getFs();
//链接到HDFS
DistributedFileSystem distributedFileSystem = (DistributedFileSystem) fileSystem;
//以数组的形式获取datanode的信息
DatanodeInfo[] data = distributedFileSystem.getDataNodeStats();
//for循环获取数组中的值
for (DatanodeInfo datanodeInfo:data){
//获取DataNode
System.out.println(datanodeInfo.getDatanodeReport());
}
}
//2、输出块数据所在节点
public static void fileStatus() throws IOException {
FileSystem fileSystem = Utils.getFs();
//根据文件的路径,指定一个所在的位置
Path path = new Path("/wc/input/a.txt");
//引入路径,获取到文件的状态
FileStatus fileStatus = fileSystem.getFileStatus(path);
BlockLocation[] blockLocations = fileSystem.getFileBlockLocations(fileStatus,0,fileStatus.getLen());
//输出块的大小,以及节点
for (int i=0;i<blockLocations.length;i++){
System.out.println(blockLocations[i]);
}
}
//3、重命名,或者移动文件
public static void renameOrMove() throws IOException {
FileSystem fileSystem = Utils.getFs();
//源文件
String srcFile="/wc/input/b2b.txt";
//目标文件
String dstFile="/wc/b2b.txt";
Path path = new Path(srcFile);
Path path1 = new Path(dstFile);
boolean bool = fileSystem.rename(path, path1);
System.out.println(bool);
}
//4、创建文件夹(省去了命令行繁琐的指令)
public static void dirOperation() throws IOException {
FileSystem fileSystem = Utils.getFs();
boolean flag = fileSystem.mkdirs(new Path("/p/p1/p2"));
String res = flag ? "成功":"失败";
System.out.println(res);
}
//5、删除
public static void deleteDir() throws IOException {
FileSystem fileSystem = Utils.getFs();
boolean bool = fileSystem.delete(new Path(("/p")));
String res = bool? "成功":"失败";
System.out.println(res);
}
//6判断文件是否存在
public static void isExist() throws IOException {
FileSystem fileSystem = Utils.getFs();
Path path = new Path("/p");
boolean bool = fileSystem.exists(path);
System.out.println(bool ?"存在":"不存在");
}
//7、HDFS创建一个文件,FSDataOutputStream属于OutputStream的一个分支,属于它的子类
public static void createFile() throws IOException {
FileSystem fileSystem = Utils.getFs();
Path path = new Path("/wc/input/a.txt");
FSDataOutputStream fsDataOutputStream =null;
byte[] buff = "this".getBytes();
try {
fsDataOutputStream = fileSystem.create(path);
// fsDataOutputStream = fileSystem.append(path);
fsDataOutputStream.write(buff,0,buff.length);
}catch (Exception e){
e.printStackTrace();
}finally {
if (fsDataOutputStream!=null){
fsDataOutputStream.close();
}
}
}
//8、读取HDFS文件,FSDataInputStream属于InputStream的一个分支,属于它的子类
public static void readFile() throws IOException {
FileSystem fileSystem = Utils.getFs();
//输入流打开文件系统的文件路径
// InputStream inputStream = fileSystem.open(new Path("/wc/input/res.txt"));
// //复制
// IOUtils.copyBytes(inputStream,System.out,4096,true);
FSDataInputStream fsDataInputStream = fileSystem.open(new Path("/wc/input/res.txt"));
IOUtils.copyBytes(fsDataInputStream,System.out,4096,true);
}
//9、上传文件(需要指定路径以及文件名)
public static void upload() throws IOException {
FileSystem fileSystem = Utils.getFs();
LocalFileSystem localFileSystem = Utils.getLocalFs();
InputStream inputStream =
localFileSystem.open(new Path("D:/办公软件/hadoop-2.7.1/README.txt"));
OutputStream outputStream = fileSystem.create(new Path("/wcc/READ.txt"));
IOUtils.copyBytes(inputStream,outputStream,4096,true);
}
//10、下载文件
public static void download() throws IOException {
FileSystem fileSystem = Utils.getFs();
FSDataInputStream inputStream = fileSystem.open(new Path("/wc/input/a.txt"));
FileOutputStream outputStream = new FileOutputStream(new File("d:\\a.txt"));
IOUtils.copyBytes(inputStream,outputStream,4096,true);
}
}