HDFS Java API 操作
新建一个Maven项目,将Hadoop的Java API包引入到项目的pom.xml文件中。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.8.2</version>
</denpendency>
注:这里并不需要非得建立一个Maven项目,只不过为了方便的管理需要引入的各种包。
大多数时候需要导入的package
import org.apache.hadoop.conf.Configuration //读取hadoop配置文件
import org.apache.hadoop.fs.FileSystem;//文件系统操作
import org.apache.hadoop.fs.Path;//读写文件等操作需要路径
import java.io.IOException;//IO异常需要catch或者throw
......
读取配置文件、设置HDFS访问地址,获取HDFS实例
Configuration conf = new Configuration();//读取hadoop配置文件,如core-site.xml、hdfs-site.xml等
conf.set("fs.default.name","hdfs://localhost:9000");//设置HDFS访问地址
FileSystem fs = FileSystem.get(conf);//取得FileSystem文件系统实例
读取文件: fs.open(path)
...
Path = new Path("hdfs:/copy.txt");
//打开输出流
InputStream in = fs.open(path);
//输出文件内容
IOUtils.copyBytes(in,System.out,conf);
//关闭输出流
IOUtils.closeStream(in);
创建目录: fs.mkdirs(path)
...
//设置需要创建的目录路径
Path path = new Path("hdfs:/mydir");
boolean isOk = fs.mkdirs(path);
if (isOk){
//成功创建目录
}
else{
//莫的创建成功
}
fs.close();
创建文件: fs.create(path)
FileSystem fs;
FSDataOutputStream out = null;
try {
fs = FileSystem.get(conf);
// 打开一个输出流
Path path = new Path("hdfs:/mydir/1.txt");
out = fs.create(path);
// 写入文件内容
out.write("Love My Precious".getBytes());
// 关闭输出流
out.close();
fs.close();
System.out.println("创建文件成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
删除文件: fs.deleteOnExit(path)
......
boolean isOk = false;
try {
fs = FileSystem.get(conf);
Path path = new Path("hdfs:/mydir/1.txt");
isOk = fs.deleteOnExit(path);
if (isOk) {
System.out.println("good");
}
else {
System.out.println("not good");
}
fs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
遍历文件和目录
private static FileSystem hdfs;
......
try {
hdfs = FileSystem.get(conf);
path = new Path("hdfs:/");
// 遍历hdfs上的其他文件和目录
FileStatus[] fs = hdfs.listStatus(path);
if (fs.length > 0) {
for (FileStatus f : fs) {
showDirs(f);
}
}
}catch (IOException e) {
e.printStackTrace();
}
private static void showDirs(FileStatus fs) throws FileNotFoundException, IOException {
Path path = fs.getPath();
// 输出文件或目录的当前路径
System.out.println(path);
// 如果是目录,则递归遍历目录下的所有文件或子目录
if (fs.isDirectory()) {
FileStatus[] f = hdfs.listStatus(path);
for (FileStatus file : f) {
showDirs(file);
}
}
}
首先调用 FileSystem 的 listStatus() 方法获得指定路径下的一级子目录和文件,将这个结果存储到 FileStatus 类型的数组中。然后遍历这个数组的每个元素,当遇到目录时再次调用 listStatus() 方法获得子目录和文件,从而遍历指定路径下的所有目录和文件。
获得文件或目录的元数据
文件或目录的元数据包括文件路径,文件修改日期,文件长度,文件备份数,文件大小等。通过使用FileSystem的getFileStatus()方法获取,返回一个FileStatus对象,将元数据封装在其中。
...
Path path = new Path("hdfs:/copy.txt");
// 获得封装目录元数据的FileStatus对象
FileStatus fileStatus = fs.getFileStatus(path);
// 判断是文件还是目录
if (fileStatus.isDirectory()) {
System.out.println("This is a directory");
}
else
{
System.out.println("This is a file");
}
// 输出元数据信息
System.out.println("File Path:" + fileStatus.getPath());
System.out.println("File modified date:"
+ new Timestamp(fileStatus.getModificationTime()).toString());
System.out.println("File last access date:"
+ new Timestamp(fileStatus.getAccessTime()).toString());
System.out.println("File length:" + fileStatus.getLen());
System.out.println("File backup number:" + fileStatus.getReplication());
System.out.println("File block size:" + fileStatus.getBlockSize());
System.out.println("File owner:" + fileStatus.getOwner());
System.out.println("File group:" + fileStatus.getGroup());
System.out.println("File permission:" + fileStatus.getPermission());
...
上传本地文件到HDFS系统
Path src = new Path("/home/hadoop/copy.txt");
Path dst = new Path("hdfs:/upload");//这里可以上传到一个目录,也可以上传重命名一个文件
//Path dst = new Path("hdfs:/222.txt");
// copy local file to HDFS System
fs.copyFromLocalFile(src, dst);
默认的方法copyFromLocalFile()只包含了src和dst两个参数,分别为本地文件路径和需要上传到的HDFS路径。该方法还有多个重载方法,添加了是否删除本地源文件、是否覆盖HDFS系统中的同名文件等。
注:在上传前需要保证HDFS系统中已经存在目标目录,否则运行不会报错但是在文件系统中并不会查找到上传的文件。
下载HDFS系统中的文件到本地
Path src = new Path("hdfs:/upload/copy.txt");
Path dst = new Path("/home/hadoop/new.txt");
fs.copyToLocalFile(src, dst);
System.out.println("Download Successful");
这里如果直接照着书上敲会报出 “Wrong FS: hdfs:/ expected file:///“ 这个错误,目前暂时不清楚具体的原因,查证后发现可以将hadoop包中的core-site.xml和hdfs-site.xml文件拷贝到该段代码所在文件的目录下即可。
参考文献
《Hadoop大数据技术开发实战》 张伟洋