我们不仅可以使用hdfs命令操作HDFS文件系统上的文件,还可以使用Java代码访问HDFS文件系统中的文件。
在Java代码中,操作HDFS主要通过以下几个主要的类:
● Configuration:用于配置HDFS。
● FileSystem:表示HDFS文件系统。
● Path:表示目录或是文件路径。
可以使用Eclipse或使用IDEA创建Java项目来操作HDFS文件系统。其中Eclipse是免费软件,IDEA有两个版本IC和IU两个版本,其中IU为IDEA Ultimate为完全功能版本,此版本需要付费后才能使用,不过我们可以选择IC版本,C为Community即社区版本的意思,IC版本为免费版本。后面我们集成开发环境将选择此IDEA Community版本。
IDEA的下载地址为https://www.jetbrains.com/idea/download/#section=windows。
选择下载IDEA Community版本,如图2-4所示。
图2-4
选择下载zip版本即可,下载完成后,解压到任意目录下(建议使用没有中文没有空格的目录)。运行IdeaIC/bin目录下的idea64.exe即可启动IDEA。接下来,我们就开始创建Java项目,并通过Java代码访问HDFS文件系统。
步骤01 创建maven项目。
打开IDEA并选择创建新的项目,如图2-5所示。
图2-5
选择创建Maven项目,如图2-6所示。
图2-6
选择项目创建的目录,并输入项目的名称,如图2-7所示。
图2-7
为了方便管理,我们以模块方式来开发,每一个章节可以为一个模块,而Hadoop是这些模块的父项目。
所以,在创建完成Hadoop项目后,修改Hadoop的项目类型为pom。以下Hadoop父项目的pom.xml文件部分内容,父项目的<package>类型为pom。
【代码2-1】hadoop/pom.xml文件
<groupId>org.hadoop</groupId> <artifactId>hadoop</artifactId> <version>1.0</version> <packaging>pom</packaging>
在父项目中的dependencyManagement添加所需要的依赖后,子模块只需要添加依赖名称,不再需要导入依赖的版本。这样父项目就起到了统一管理版本的功能。
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> </dependency> </dependencies> </dependencyManagement>
现在我们再创建第一个模块。选择Hadoop项目,选择创建模块,如图2-8所示。
图2-8
输入模块的名称,如图2-9所示。
图2-9
在创建的子模块chapter01中,修改pom.xml文件,添加以下依赖。注意,只输入groupId和artifactId,不需要输入版本,因为Hadoop项目作为父项目管理依赖的版本。
<dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies>
查看hadoop client Aggretator的依赖关系,如图2-10所示。
图2-10
至此我们已经可以开发Java代码,访问HDFS文件系统了。
步骤02 HDFS操作示例。
(1)显示HDFS指定目录下的所有目录
显示所有目录,使用fileSystem.listStatus方法。
【代码2-2】Demo01AccessHDFS.java
1. System.setProperty("HADOOP_USER_NAME", "hadoop"); 2. Configuration config = new Configuration(); 3. config.set("fs.defaultFS", "hdfs://192.168.56.201:8020"); 4. FileSystem fs = FileSystem.get(config); 5. FileStatus[] stas = fs.listStatus(new Path("/")); 6. for (FileStatus f : stas) { 7. System.out.println(f.getPermission().toString() + " " 8. + f.getPath().toString()); 9. } 10. fs.close();
输出的结果如下所示:
rwxr-xr-x hdfs://192.168.56.201:8020/test
代码说明:
● 第1行代码用于设置访问Hadoop的用户名。
● 第2行代码用于声明一个新的访问配置对象。
● 第3行代码设置访问的具体地址。
● 第4行代码创建一个文件系统对象。
● 第5行~8行代码为输出根目录下的所有文件或目录,不包含子目录。
● 第9行代码关闭文件系统。
(2)显示所有文件
显示所有文件,使用fileSystem.listFiles函数,第二个参数boolean用于指定是否递归显示所有文件。
【代码2-3】Demo02ListFiles.java
1. System.setProperty("HADOOP_USER_NAME", "hadoop"); 2. Configuration config = new Configuration(); 3. config.set("fs.defaultFS", "hdfs://192.168.56.201:8020"); 4. FileSystem fs = FileSystem.get(config); 5. RemoteIterator<LocatedFileStatus> files = 6. fs.listFiles(new Path("/"), true); 7. while(files.hasNext()){ 8. LocatedFileStatus file = files.next(); 9. System.out.println(file.getPermission()+" "+file.getPath()); 10. } 11. fs.close();
添加了true参数以后,执行的结果如下所示:
rw-r--r-- hdfs://192.168.56.201:8020/test/a.txt
(3)读取HDFS文件的内容
读取HDFS上的内容,可以和fileSystem.open(...)打开一个文件输入流,然后读取文件流中的内容即可。
【代码2-4】Demo03ReadFile.java
1. String server = "hdfs://192.168.56.201:8020"; 2. System.setProperty("HADOOP_USER_NAME", "hadoop"); 3. Configuration config = new Configuration(); 4. config.set("fs.defaultFS", server); 5. try (FileSystem fs = FileSystem.get(config)) { 6. DataInputStream in = fs.open(new Path(server+"/test/a.txt")); 7. int len = 0; 8. byte[] bs = new byte[1024]; 9. while((len=in.read(bs))!=-1){ 10. String str = new String(bs,0,len); 11. System.out.print(str); 12. }}
(4)向HDFS写入数据
向HDFS写入数据,可以使用fileSysten.create/append方法,获取一个OutputStream,然后向里面输入数据即可。
【代码2-5】4 Demo04WriteFile.java
1. String server = "hdfs://192.168.56.201:8020"; 2. System.setProperty("HADOOP_USER_NAME", "hadoop"); 3. Configuration config = new Configuration(); 4. config.set("fs.defaultFS", server); 5. try (FileSystem fs = FileSystem.get(config)) { 6. OutputStream out = fs.create(new Path(server+"/test/b.txt")); 7. out.write("Hello Hadoop\n".getBytes()); 8. out.write("中文写入测试\n".getBytes()); 9. out.close(); 10. }
代码输入完成以后,通过cat查看文件中的内容:
[hadoop@server201 ~]$ hdfs dfs -cat /test/b.txt Hello Hadoop 中文写入测试
其他更多方法不再赘述,这些方法简述如下:
● mkdirs:创建目录。
● create:创建文件。
● checkPath:创建一个文件检查点。
● delete:删除文件。