您的位置:首页 > 大数据 > Hadoop

Apache Hadoop 使用Java API操作HDFS之代码实现文件夹遍历文件上传下载

2019-03-07 20:39 531 查看

先放maven依赖POM.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycat</groupId>
<artifactId>javaapihdfs</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

测试类准备(单元测试):

每个测试方法运行前必须运行的初始化方法:(@BeforeClass注解)

private static FileSystem fs;
@BeforeClass
public static void init() throws URISyntaxException, IOException, 			    InterruptedException {
URI uri=new URI("hdfs://192.168.183.81:9000");
Configuration conf=new Configuration();
fs = FileSystem.get(uri, conf, "hadoop");
}

每个测试方法运行结束后必定运行关闭资源方法:(@AfterClass注解)

@AfterClass
public static void destroy() throws IOException {
if(null!=fs){
fs.close();
}
}

Part One

使用Java API如何实现对HDFS上某一个文件夹下文件信息的递归遍历?

@Test
public void testLs() throws IOException {
Path origin=new Path("/mktest");// hdfs目录树下的/mktest目录
RemoteIterator<LocatedFileStatus> status = fs.listFiles(origin, true);
while(status.hasNext()){
LocatedFileStatus fileStatus = status.next();
System.out.println("路径:"+fileStatus.getPath());
System.out.println("副本数:"+fileStatus.getReplication());
System.out.println("文件大小:"+fileStatus.getLen());
System.out.println();
}
}

输出结果展示

路径:hdfs://192.168.183.81:9000/mktest/a.txt
副本数:3
文件大小:0

路径:hdfs://192.168.183.81:9000/mktest/hadoop-2.7.7-centos-6.7.tar.gz
副本数:3
文件大小:199076243

路径:hdfs://192.168.183.81:9000/mktest/test.md
副本数:3
文件大小:3334

Part Two

如何使用Java API实现从本地文件系统上传文件到HDFS?

方案一:(copyFromLocal方法)

@Test
public void testUpload() throws URISyntaxException, IOException, InterruptedException {
Path origin=new Path("D:\\share\\hadoopBase/hadoop-eclipse-plugin-2.6.5.jar");
Path goal=new Path("/mktest");
fs.copyFromLocalFile(origin, goal);
}

方案二:(使用IOUtils包装流的copyBytes方法)

@Test
public void testIOUpload() throws IOException {
InputStream in = new FileInputStream("D:\\share\\hadoopBase/hadoop-eclipse-plugin-2.6.5.jar");
FSDataOutputStream out = fs.create(new Path("/mktest/hadoop-eclipse-plugin-2.6.5.jar"));
IOUtils.copyBytes(in, out, 2048, true);
}

结果

[hadoop@mycat01 ~]$ hdfs dfs -ls /mktest
Found 4 items
-rw-r--r--   3 hadoop hadoop          0 2019-03-06 02:02 /mktest/a.txt
-rw-r--r--   3 hadoop hadoop  199076243 2019-03-06 07:12 /mktest/hadoop-2.7.7-centos-6.7.tar.gz
-rw-r--r--   3 hadoop hadoop   32188216 2019-03-07 11:40 /mktest/hadoop-eclipse-plugin-2.6.5.jar
-rw-r--r--   3 hadoop hadoop       3334 2019-03-06 09:45 /mktest/test.md

上传成功,但是需要注意的是,第二种方案,目标文件名需要指定,不能只给定文件夹。

Part Three

如何使用Java API实现从HDFS文件系统下载文件到本地文件系统?

方案一:(copyToLocal方法)

@Test
public void testDownload() throws URISyntaxException, IOException, InterruptedException {
Path origin=new Path("/mktest/hadoop-eclipse-plugin-2.6.5.jar");
Path goal=new Path("D:/");
fs.copyToLocalFile(origin, goal); // 不成功的话先改用下面的四个参数的方法
// fs.copyToLocalFile(false,origin, goal,true);
}

方案二:(使用IOUtils包装流的copyBytes方法)

@Test
public void testIODownload() throws IOException {
FSDataInputStream in = fs.open(new Path("/mktest/hadoop-eclipse-plugin-2.6.5.jar"));
OutputStream out=new FileOutputStream("D:/hadoop-eclipse-plugin-2.6.5.jar");
IOUtils.copyBytes(in, out, 2048, true);
}

下载成功,但是需要注意的是,第二种方案,目标文件名需要指定,不能只给定文件夹。

Part Four

上面下载采用

方案一
的话,即使用
fs.copyToLocalFile(origin, goal)
进行下载的话会生成crc文件。这是为什么呢?

如果你使用两个参数没有报错的话,说明你已经解决了某个问题,这里采用两个参数的

copyToLocalFile
方法会生成crc校验文件,用来校验从hdfs拿过来的文件是否是完整的。所以你完全可以采用四个参数的方法。不生成crc校验文件,这个对应其第四个参数,即
useRawLocationFileSystem=true
。默认情况下这个值为false,即下载的时候需要crc校验文件。第一个参数是delSrc,即是否删除源文件,作用,你懂的。

如果你使用两个参数报错:

(null) entry in command string: null chmod 0644 xxx

方案一:下载winutils.exe以及hadoop相关配置文件,配置到Path中去

如果日志中报hadoop.tmp.dir没有设置,或者没有找到winutils.exe,此方案也可以解决。(亲试)

下载:winutils.exe和hadoop.dll等

解压到当前目录下,然后进入

hadoopwinutils
,拷贝文件夹路径,新建环境变量HADOOP_HOME,并把%HADOOP_HOME%\bin配置到PATH中。

然后重启电脑,重启Hadoop集群,搞定。

方案二:CSDN上看到别人说的,自己没试过

hadoop.dll文件在上面方案一中压缩包也有

下载hadoop.dll文件

并拷贝到c:\windows\system32目录中

然后重新运行代码程序即可

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐