源码地址
springboot2教程系列
org.apache.hadoop
hadoop-client
2.7.3
org.slf4j
slf4j-log4j12
javax.servlet
servlet-api
org.apache.hadoop
hadoop-common
2.7.3
org.slf4j
slf4j-log4j12
javax.servlet
servlet-api
org.apache.hadoop
hadoop-hdfs
2.7.3
org.slf4j
slf4j-log4j12
javax.servlet
servlet-api
hadoop.name-node: hdfs://10.10.1.142:9000
hadoop.namespace: /nias
@Configuration
@ConditionalOnProperty(name="hadoop.name-node")
@Slf4j
public class HadoopConfig {
@Value("${hadoop.name-node}")
private String nameNode;
@Bean("fileSystem")
public FileSystem createFs(){
//读取配置文件
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
//conf.set("fs.defalutFS", "hdfs://192.168.169.128:9000");
conf.set("dfs.replication", "1");
//指定访问hdfs的客户端身份
//fs = FileSystem.get(new URI("hdfs://192.168.169.128:9000/"), conf, "root");
// 文件系统
FileSystem fs = null;
// 返回指定的文件系统,如果在本地测试,需要使用此种方法获取文件系统
try {
URI uri = new URI(nameNode.trim());
fs = FileSystem.get(uri,conf);
} catch (Exception e) {
log.error("", e);
}
return fs;
}
}
Configuration conf=new Configuration();
创建一个Configuration对象时,其构造方法会默认加载hadoop中的两个配置文件,分别是hdfs-site.xml以及core-site.xml,这两个文件中会有访问hdfs所需的参数值,主要是fs.default.name,指定了hdfs的地址,有了这个地址客户端就可以通过这个地址访问hdfs了。即可理解为configuration就是hadoop中的配置信息。
可以通过Configuration.addResource(“xml的名字”);(前提这个xml放在当前jar包目录或者hadoop的配置的目录)来读取这个配置文件里面的内容
@Component
@ConditionalOnBean(FileSystem.class)
@Slf4j
public class HadoopTemplate {
@Autowired
private FileSystem fileSystem;
@Value("${hadoop.name-node}")
private String nameNode;
@Value("${hadoop.namespace:/}")
private String nameSpace;
@PostConstruct
public void init(){
existDir(nameSpace,true);
}
public void uploadFile(String srcFile){
copyFileToHDFS(false,true,srcFile,nameSpace);
}
public void uploadFile(String srcFile,String destPath){
copyFileToHDFS(false,true,srcFile,destPath);
}
public void delFile(String fileName){
rmdir(nameSpace,fileName) ;
}
public void delDir(String path){
nameSpace = nameSpace + "/" +path;
rmdir(path,null) ;
}
public void download(String fileName,String savePath){
getFile(nameSpace+"/"+fileName,savePath);
}
/** * 创建目录 * @param filePath * @param create * @return */
public boolean existDir(String filePath, boolean create){
boolean flag = false;
if(StringUtils.isEmpty(filePath)){
throw new IllegalArgumentException("filePath不能为空");
}
try{
Path path = new Path(filePath);
if (create){
if (!fileSystem.exists(path)){
fileSystem.mkdirs(path);
}
}
if (fileSystem.isDirectory(path)){
flag = true;
}
}catch (Exception e){
log.error("", e);
}
return flag;
}
/** * 文件上传至 HDFS * @param delSrc 指是否删除源文件,true为删除,默认为false * @param overwrite * @param srcFile 源文件,上传文件路径 * @param destPath hdfs的目的路径 */
public void copyFileToHDFS(boolean delSrc, boolean overwrite,String srcFile,String destPath) {
// 源文件路径是Linux下的路径,如果在 windows 下测试,需要改写为Windows下的路径,比如D://hadoop/djt/weibo.txt
Path srcPath = new Path(srcFile);
// 目的路径
if(StringUtils.isNotBlank(nameNode)){
destPath = nameNode + destPath;
}
Path dstPath = new Path(destPath);
// 实现文件上传
try {
// 获取FileSystem对象
fileSystem.copyFromLocalFile(srcPath, dstPath);
fileSystem.copyFromLocalFile(delSrc,overwrite,srcPath, dstPath);
//释放资源
// fileSystem.close();
} catch (IOException e) {
log.error("", e);
}
}
/** * 删除文件或者文件目录 * * @param path */
public void rmdir(String path,String fileName) {
try {
// 返回FileSystem对象
if(StringUtils.isNotBlank(nameNode)){
path = nameNode + path;
}
if(StringUtils.isNotBlank(fileName)){
path = path + "/" +fileName;
}
// 删除文件或者文件目录 delete(Path f) 此方法已经弃用
fileSystem.delete(new Path(path),true);
} catch (IllegalArgumentException | IOException e) {
log.error("", e);
}
}
/** * 从 HDFS 下载文件 * * @param hdfsFile * @param destPath 文件下载后,存放地址 */
public void getFile(String hdfsFile,String destPath) {
// 源文件路径
if(StringUtils.isNotBlank(nameNode)){
hdfsFile = nameNode + hdfsFile;
}
Path hdfsPath = new Path(hdfsFile);
Path dstPath = new Path(destPath);
try {
// 下载hdfs上的文件
fileSystem.copyToLocalFile(hdfsPath, dstPath);
// 释放资源
// fs.close();
} catch (IOException e) {
log.error("", e);
}
}
}
从HDFS下载文件时候报 (null) entry in command string: null chmod 0644 错误。
解决方法:
在 https://github.com/SweetInk/hadoop-common-bin 中下载hadoop.dll,并拷贝到c:\windows\system32目录中
然后重新运行代码程序即可