Java Api操作HDFS
使用idea工具
创建的是maven项目,操作linux环境
首先需要配置好Maven环境,如果下载jar包下的慢,可以将镜像站换为阿里云的镜像【配置maven环境参考:...............(待完成)】
准备工作完成即可开始编写代码
1.创建maven项目
2.在pom.xml里面导入依赖
pom.xml中所使用到的jar包【自行去maven仓库找jar包,认准下载量最多的。https://mvnrepository.com/】
如果网站加载的太慢,可以去阿里云的maven仓库找:https://maven.aliyun.com/
hadoop-common,hadoop-hdfs,hadoop-client【3个版本保持一致】
<dependencies> <!--测试用--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--COMMON是hadoop一切的核心,不是具体的功能,操作HDFS需要导入COMMON的依赖--> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.7.3</version> </dependency> <!--hadoop也是基于客户端服务器的--> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.3</version> </dependency> <!--操作MapReduce需要HDFS的依赖--> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.7.3</version> </dependency> </dependencies>
3.开始编写代码
3.1.连接HDFS
//连接HDFS @Test //测试 public void connectHDFS(){ //先添加一个配置文件--和core-site.xml的配置一样[相当于服务器的端口] Configuration conf = new Configuration(); //配置服务器的地址和端口 conf.set("fs.defaultFS","hdfs://192.168.0.10:9000"); try { //加载我们的配置文件,然后连接到服务上去【前提,hadoop的环境配好,启动起来】 FileSystem fileSystem = FileSystem.get(conf); //如何判断是否已经连上? //getFileStatus是获取当前某个路径的状态 FileStatus status = fileSystem.getFileStatus(new Path("/test.txt")); System.out.println(status.isFile()); //判断是不是一个文件 System.out.println(status.isDirectory()); //判断是不是一个目录 System.out.println(status.getPath()); //获取文件的路径 System.out.println(status.getLen()); //获取文件的大小 //关闭连接 fileSystem.close(); } catch (IOException e) { e.printStackTrace(); } }
3.2.文件上传到HDFS【linux命令:hadoop fs -put】
//上传文件到HDFS @Test //测试 public void upload1(){ //添加配置文件 Configuration conf = new Configuration(); //如果报一个错误: //user=Machenike, access=WRITE, inode="/":root:supergroup:drwxr-xr-x //解决1:直接添加System.setProperty("HADOOP_USER_NAME", "root"); 设置为root用户 //解决2:在环境变量中添加 HADOOP_USER_NAME 值为root System.setProperty("HADOOP_USER_NAME", "root"); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //获取一个输出流 FSDataOutputStream out = fileSystem.create(new Path("/upload.txt")); //获取本地文件的一个输入流 FileInputStream in = new FileInputStream(new File("F:\\upload.txt")); //先定义一个byte类型的数组,数组长度1024 //该数组的大小表示每次从文件中读取出来的数据量 byte[] b = new byte[1024]; int len = 0; //判断文件是否读完 while((len=in.read(b))!=-1){ //对这些数据量进行输出 //b-表示要写的数据,0-表示从0开始,len-表示写的字节数 out.write(b,0,len); } //将输入流和输出流关闭 in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } //文件上传方式2-直接使用hadoop提供的一个工具类IOUtils @Test //测试 public void upload2(){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //获取一个输出流 FSDataOutputStream out = fileSystem.create(new Path("/upload1.txt")); //获取本地文件的一个输入流 FileInputStream in = new FileInputStream(new File("F:\\upload.txt")); //执行上传操作 IOUtils.copyBytes(in,out,conf); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }
可能会遇到如下错误:如何解决?
解决办法:
1.直接在代码中设置属性->System.setProperty("HADOOP_USER_NAME", "root");
2.在环境变量中添加HADOOP_USER_NAME 值为root即可【如果不行,重启idea,再不行就重启电脑就OK了】
3.3.从HDFS上下载文件到本地【linux命令:hadoop fs -get】
//文件下载 @Test public void download(){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //获取输入流的数据 FSDataInputStream in = fileSystem.open(new Path("/upload.txt")); //获取本地文件的输出流 FileOutputStream out = new FileOutputStream(new File("F:\\download.txt")); //下载的方式同样有两种【下载就是拷贝】 //方式1:工具类操作 // IOUtils.copyBytes(in,out,conf); //方式2: byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ out.write(b,0,len); } //关闭连接 in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }
3.4.修改HDFS下的文件名
//重命名 @Test //测试 public void rename(){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //重命名 boolean rename = fileSystem.rename(new Path("/upload.txt"), new Path("/upload3.txt")); System.out.println(rename?"修改成功":"修改失败"); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }
3.5.创建文件夹【linux命令:hadoop fs -mkdir -p】
//创建文件夹 @Test //测试 public void mkdirs(){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //创建多级目录 boolean mkdirs = fileSystem.mkdirs(new Path("/test/test1/hello.txt")); System.out.println(mkdirs?"城建成功":"创建失败"); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }
3.6.查看所有文件夹【linux命令:hadoop fs -lsr】
//查看所有文件夹 @Test //测试 public void selectAll(){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //查询该路径下所有的文件信息 FileStatus[] status = fileSystem.listStatus(new Path("/")); //遍历所有的文件的状态 System.out.println("/"); for (FileStatus f:status){ //判断是否是文件 //f.getPath().getName() 获取文件或文件夹的名字 //f.getPermission() 获取文件或文件夹的权限 //f.getLen() 获取文件或文件夹的大小 if (f.isFile()){ System.out.println("f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen()); }else{ System.out.println("d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen()); getNodes(f.getPath().getName(), 1); } } } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } //递归遍历出所有的文件和文件夹【index主要就是为了打印出来的好看些,强迫症】 public void getNodes(String dir, int index){ //添加配置文件 Configuration conf = new Configuration(); try { //加载配置文件 FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.0.10:9000"), conf); //得到之后新目录的绝对路径 String path = "/"+dir; //使其具有层次感的制表符 String tab = "\t"; if(index > 1){ for(int i = 1; i < index; i++){ tab += "\t"; } } //获取该路径下的所有文件信息 FileStatus[] status = fileSystem.listStatus(new Path(path)); //设置让其退出的条件【如果该路径下没有文件或文件夹即退出】 if(status.length==0){ return; } //遍历所有的文件信息 for (FileStatus f : status){ if (f.isFile()){ System.out.println(tab+"f--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen()); }else{ System.out.println(tab+"d--"+f.getPath().getName()+"\t"+f.getPermission()+"\t"+f.getLen()); getNodes(dir +"/"+f.getPath().getName(), index +1); } } } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }
结果如下:
使用Eclipse工具
需要自己导入jar包。jar包如何找?【将hadoop-2.7.7.tar.gz包解压即可】
jar包 -- 操作hdfs,需要导入Common下的jar包
share/hadoop/common/lib下面作者引用别人的jar包
share/hadoop/common下面自己写的jar包
-- 操作MapReduce,还需要导入HDFS下的jar包
share/hadoop/hdfs/lib 下面作者引用别人的jar包
share/hadoop/hdfs 下面作者自己写的包
代码部分和idea一样的操作