说明:在IDEA集成环境中利用JAVA API实现目录的创建、文件的创建、文件的上传和下载、文件的查看、文件删除、文件的编辑等操作。以下代码均创建在my.dfs
包下
创建文件夹
在hdfs系统的根目录下创建文件夹 /hdfstest
验证程序执行结果:
$hadoop fs -ls -R /
package my.hdfs;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
在hdfs系统的根目录下创建文件夹 /hdfstest
*/
public class MakeDir {
public static void main(String[] args) throws IOException, URISyntaxException {
// 创建 Configuration 对象
Configuration conf = new Configuration();
// FileSystem默认的端口号:9000
String hdfsPath = "hdfs://localhost:9000";
// 获取 FileSystem 对象
FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
String newDir = "/hdfstest";
// 如果创建成功将返回true
boolean result = hdfs.mkdirs(new Path(newDir));
if (result) {
System.out.println("Success!");
} else {
System.out.println("Failed!");
}
}
}
迭代文件夹获取文件信息
设置文件夹,迭代获取其下的文件和文件信息(权限、所有者、所在组、文件所在路径)
package my.hdfs;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
public class IteratorListFiles {
public static void main(String[] args) throws IOException {
FileSystem hdfs = FileSystem.get(URI.create("hdfs://localhost:9000/"), new Configuration());
String watchHDFS = "/";
iteratorListFile(hdfs, new Path(watchHDFS));
}
public static void iteratorListFile(FileSystem hdfs, Path path) throws IOException {
FileStatus[] files = hdfs.listStatus(path);
for (FileStatus file: files) {
if (file.isDirectory()) {
System.out.println("dir:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
} else if(file.isFile()){
System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
}
}
}
}
操作文件
创建、重命名、删除文件、判断文件是否存在
package my.hdfs;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
创建、重命名、删除文件、判断文件是否存在、迭代文件夹获取其下的文件和文件夹信息
*/
public class OperateFile {
public static void main(String[] args) throws IOException, URISyntaxException {
// 创建 Configuration 对象
Configuration conf = new Configuration();
// FileSystem默认的端口号:9000
String hdfsPath = "hdfs://localhost:9000";
// 获取 FileSystem 对象
FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
// 1. 迭代 /hdfstest 文件夹下所有的文件文件
String watchHDFS = "/hdfstest";
FileStatus[] files = hdfs.listStatus(new Path(watchHDFS));
for (FileStatus file: files){
if (file.isFile()) {
System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
}
}
System.out.println("----------Operate file----------");
// 2. create file。如果文件所在的文件夹不存在,那么会自动创建文件夹
String filePath = "/hdfstest/src_data";
FSDataOutputStream create = hdfs.create(new Path(filePath));
System.out.println("create file successfully!" + create);
// 3. 重命名 hdfs.rename() src_data -> dst_data
Path src = new Path("/hdfstest/src_data");
Path dst = new Path("/hdfstest/dst_data");
System.out.println("rename file successfully?" + hdfs.rename(src, dst));
// 判断文件是否存在 hdfs.exist() /hdfstest/src_data
System.out.println("after rename,src_data is still exist?" + hdfs.exists(src));
// 4. 删除文件 hdfs.delete() dst_data
hdfs.delete(dst, true);
// 判断文件是否存在 /hdfstest/dst_data
System.out.println("after delete(), dst_data is still exist?" + hdfs.exists(dst));
System.out.println("----------Operate file----------");
// 5. 迭代 /hdfstest 文件夹下所有的文件文件
for (FileStatus file: files){
if (file.isFile()) {
System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
}
}
}
}
写入文件信息
在HDFS文件系统中创建/hdfstest/writefile
文件,在文件中写入内容hello world hello data!
验证程序执行结果:
$hadoop fs -ls -R /hdfstest
$hadoop fs -cat /hdfstest/writefile
api实现代码:
package my.hdfs;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.Configuration;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/*
在HDFS文件系统中创建 /hdfstest/writefile 文件并在文件中写入内容 hello world hello data!
*/
public class WriteFile{
public static void main(String[] args) throws IOException, URISyntaxException {
// FileSystem.get(Configuration conf) 使用配置文件来获取文件系统, 配置文件conf/core-site.xml,若没有指定则返回local file system. (原来是这样)
// FileSystem.get(URI uri, Configuration conf) 根据uri和conf来确定文件系统
// 若 hdfs系统的uri 写错,则会默认为local文件系统,从当前java的Project文件所在的位置
FileSystem hdfs = FileSystem.get(new URI("hdfs//localhost:9000"), new Configuration());
String filePath = "/hdfstest/writefile";
FSDataOutputStream create = hdfs.create(new Path(filePath));
System.out.println("Step 1 Finish!");
String sayHi = "hello world hello data!";
byte[] buff = sayHi.getBytes();
create.write(buff, 0, buff.length);
create.close();
System.out.println("Step 2 Finish!");
}
}
合并文件内容
首先进入本地/data/hadoop目录下,将该目录下的所有文件删除(此时要求/data/hadoop中必须全是文件,不能有目录)。
$cd /data/hadoop
$sudo rm -r /data/hadoop/*
然后在该目录下新建两文件,分别命名为file1、file2。
$touch file1
$touch file2
向 file1 和 file2 中,分别输入内容如下
$echo "hello file1" > file1
$echo "hello file2" > file2
在 my.hdfs 包下,新建类 PutMerge
,将 Linux 本地文件夹/data/hadoop/
下的所有文件,上传到HDFS上并合并成一个文件/hdfstest/mergefile
验证程序执行结果:
$hadoop fs -ls /hdfstest
api代码实现
package my.hdfs;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.Configuration;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
将/data/hadoop下的所有文件上传至HDFS并合并文件内容
*/
public class PutMerge{
public static void main(String[] args) throws IOException, URISyntaxException {
Configuration conf = new Configuration();
FileSystem hdfs = FileSystem.get(new URI("hdfs://localhost:9000"), conf);
FileSystem local = FileSystem.getLocal(conf);
String from_LinuxDir = "/data/hadoop/";
String to_HDFS = "/hdfstest/mergefile";
FileStatus[] inputFiles = local.listStatus(new Path(from_LinuxDir));
FSDataOutputStream out = hdfs.create(new Path(to_HDFS));
for (FileStatus file: inputFiles) {
FSDataInputStream in = local.open(file.getPath());
byte[] buffer = new byte[256];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
in.close();
}
System.out.println("Finish!");
}
}
文件上传与下载
HDFS文件下载至本地
- 在
/data/hadoop/
下创建目录 copytolocal。
$mkdir /data/hadoop/copytolocal
- 在my.hdfs包下,创建类
CopyToLocalFile
,程序功能是将 HDFS 文件系统上的文件/hdfstest/sample_data
,下载到本地/data/hadoop/copytolocal
- 验证程序执行结果:
$cd /data/hadoop/copytolocal
$ls
api实现代码:
package my.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
将 HDFS 文件系统中的文件下载到本地 Linux 系统
*/
public class CopyToLocalFile{
public static void main(String[] args) throws URISyntaxException, IOException {
Configuration conf = new Configuration();
String hdfsPath = "hdfs://localhost:9000";
FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
String from_HDFS = "/hdfstest/sample_data";
String to_Local = "/data/hadoop/copytolocal";
hdfs.copyToLocalFile(false, new Path(from_HDFS), new Path(to_Local));
System.out.println("Finish!");
}
}
/hdfstest/sample_data
等价于hdfs://localhost:9000/hdfstest/sample_data
若删除/
,则hdfstest/sample_data
表示:?
若无法将文件移至/data/hadoop/copytolocal
,即为权限不够,终端输入:chomd -R 777 /data/hadoop/copytolocal
本地文件上传至HDFS
- 在 /data/hadoop 下创建 sample_data 文件
$cd /data/hadoop
$touch sample_data
- sample_data 文件中写入
hello world
$echo "hello file1" > sample_data
- 在 my.hdfs 包下,创建类``CopyFromLocalFile.java
,将本地 Linux 操作系统上的文件
/data/hadoop/sample_data,上传到 HDFS 文件系统的
/hdfstest` 目录下。 - 验证程序执行结果:
$hadoop fs -ls -R /
api实现代码:
package my.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/*
将本地文件上传到 HDFS 文件系统
*/
public class CopyFromLocalFile{
public static void main(String[] args) throws IOException, URISyntaxException {
Configuration conf = new Configuration();
String hdfsPath = "hdfs://localhost:9000";
FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
String from_Linux = "/data/hadoop/sample_data";
String to_HDFS = "/hdfstest";
hdfs.copyFromLocalFile(new Path(from_Linux), new Path(to_HDFS));
System.out.println("Finish!");
}
}
文件块信息
在 my.hdfs 包下,新建类 LocateFile,程序功能是查看 HDFS 文件系统上,文件/hdfstest/sample_data
的文件块信息
package my.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class LocateFile{
public static void main(String[] args) throws URISyntaxException, IOException {
FileSystem hdfs = FileSystem.get(new URI("hdfs://localhost:9000"), new Configuration());
Path file = new Path("/hdfstest/sample_data");
FileStatus fileStatus = hdfs.getFileStatus(file);
BlockLocation[] location = hdfs.getFileBlockLocations(fileStatus, 0, fileStatus.getLen());
for (BlockLocation block: location) {
String[] hosts = block.getHosts();
for (String host: hosts){
System.out.println("block:" + block + "host:" + host);
}
}
}
}
获取FileSystem对象,详见:JAVA API实现HDFS操作(一)获取FileSystem
用Java API实现HDFS操作过程中的常见问题,详见:用Java API实现HDFS操作(三)问题汇总