大数据hadoop学习【6】-----通过JAVA编程实现对HDFS文件操作的JAVA整体项目

大数据hadoop学习【6】-----通过JAVA编程实现对HDFS文件操作的JAVA整体项目目录


通过JAVA实现对HDFS文件个各种操作,一直是hadoop基础学习的重要步骤,也是基础知识,所以,这对JAVA编程的能力有一定的要求,在JAVA的基础上,学习好hadoop!本次博客,林君学长将带大家如何利用JAVA做一个对HDFS文件操作的整体项目,内容如下:

  1. 向HDFS上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件
  2. 从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名
  3. 将HDFS中指定文件的内容输出到终端中
  4. 显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息
  5. 给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息,如果该文件是目录,则递归输出该目录下所有文件相关信息
  6. 提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录
  7. 在HDFS中,将文件从源路径移动到目的路径

一、JAVA项目的整体结构介绍

1、项目目录展示

1)、整体项目的目录截图如下:
在这里插入图片描述
其中src源代码包可以不用看,主要功能在hdfs和view包中的class文件

2、项目中类的功能的解释

1)、在文件包view包下面菜单类的讲解
有上面项目图可以看出,我们选择文件的菜单主要是通过Menu进行菜单选择,该java文件中包含了菜单选择的功能!
2)、在文件包hdfsFile包下面的功能文件的讲解
该系统目录中各个类的功能如下所示:
在这里插入图片描述

3、项目文件数据准备

1)、ubuntu本地的文件数据
在ubuntu本地文件,自己找到对应的位置,新建几个txt文件,为后面的文件操作做准备,比如,林君学长的数据如下:
在这里插入图片描述
分别对应的文件内容如下所示:
在这里插入图片描述
在这里插入图片描述
2)、HDFS中的文件数据
当然,自己在HDFS相关文件夹下也应该创建一下相应的文件,这里就不再教大家如何利用shell命令创建文件了,大家可以去林君学长之前写的Hdfs与shell命令的交互博客下去查看哦!林君学长路径下的文件如下:
在这里插入图片描述

二、题目要求内容的分步讲解

1、 向HDFS上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件

1)、创建UploadHdfs类,并写入实现以上功能代码

package hdfsFileOperations;
import java.net.URI;
import java.util.Scanner;
import java.io.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public class UploadHdfs {
	//本地文件上传到Hdfs
	public void uploadFile() throws IOException{
		String src="/home/chenlin/lenovo/file/data.txt";
		String name="/data.txt";
		String dst="/user/hadoop/input";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path srcPath = new Path(src);//原路径
		Path dstPath1 = new Path(dst+name);//目标路径+文件名,用于判断文件是够在目标路径存在
		Path dstPath = new Path(dst+name);//目标路径
		//判断是否存在相同名称的文件
		if(!fs.exists(dstPath1))//不存在,直接复制
		{
			fs.copyFromLocalFile(false,srcPath, dstPath);//(false不删除本地文件;true删除本地文件,原路径,目标路径)
		}
		else//若存在,由用户选择上传方式
		{
		    System.out.println("温馨提示:该文件已经存在,你可以选择如下选项进行操作");
		    System.out.println("1、覆盖原文件");
		    System.out.println("2、添加到文件末尾");
		    System.out.println("0、退出");
		    System.out.print("请输入你的选择");
		    Scanner in=new Scanner(System.in); 
		    int x=in.nextInt();
		    if(x==1)
		    {
				fs.copyFromLocalFile(false,srcPath, dstPath);
		    }
			else if(x==2)
				appendFile(src,dst);
			else if(x==0)
				return;
		}
		System.out.println("上传成功!");
	}
	//添加到文件末尾
	public void appendFile(String src,String dst) throws IOException{
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path dstPath = new Path(dst);
		InputStream in = new BufferedInputStream(new FileInputStream(src));
		FSDataOutputStream out = fs.append(dstPath);
		IOUtils.copyBytes(in,out,4096,true);
		fs.close();
	}
}

2)、以上java程序的实现功能

将本地路径下 /home/用户/lenovo/file/data.txt的data.txt文件上传到Hdfs文件系统的input目录下去,如果文件存在,则由我们觉得是覆盖文件还是添加到文件尾部!

2、从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名

1)、创建DownloadHdfs类,写入实现该题目工程的java程序

package hdfsFileOperations;
import java.net.URI;
import java.util.Scanner;
import java.io.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public class DownloadHdfs {
	public void download() throws IOException{
		String oldPath="/user/hadoop/input/data.txt";
		String name="data.txt";
		String newPath="/home/chenlin/lenovo/file/";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path ofile = new Path(oldPath);
		File nfile1=new File(newPath+name);
		File nfile=new File(newPath);
		FSDataInputStream in = fs.open(ofile);
		if(!nfile1.exists())
		{
			FileOutputStream out =  new FileOutputStream(nfile);
			IOUtils.copyBytes(in,out,2048,true);
		}
		else{
			Scanner sc=new Scanner(System.in); 
			System.out.print("该文件在本地已经存在,请修改文件名称:");
		    String new2=sc.next();
		    File newfile = new File(newPath+new2);
			FileOutputStream out = new FileOutputStream(newfile);
			IOUtils.copyBytes(in,out,2048,true);
		}
		System.out.println("文件下载到本地成功!");
	}
	//文件重命名
	public void rename(String oldname,String newname) throws IOException{
	     	Configuration conf = new Configuration();
	     	conf.set("fs.defaultFS","hdfs://localhost:9000");
	        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
			FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
			Path oldPath = new Path(oldname);
			Path newPath = new Path(newname);
			boolean flag = fs.rename(oldPath,newPath);
			if(flag){
				System.out.println("重命名成功!");
			}else{
				System.out.println("重命名失败!");
			}
		}
}

2)、程序功能解释

该程序的功能是将刚刚上传到HDFS文件系统input目录下的data.txt文件再次传回本地file文件夹下面去

3、将HDFS中指定文件的内容输出到终端

1)、在eclipse中创建OutputHdfsTOTerminal类,并写入实现该题目功能的java程序

package hdfsFileOperations;
import java.net.URI;
import java.io.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public class OutputHdfsTOTerminal {
	//文件内容输出到终端
	public void displayFile() throws IOException{
		String uri="/user/hadoop/input/Merge.txt";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		InputStream in = null;
		try{
			in = fs.open(new Path(uri));
			IOUtils.copyBytes(in,System.out,4096,false);
			System.out.println("输出到终端成功!");
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			IOUtils.closeStream(in);
		}
	}
}

2)、java代码功能解释

以上代码是将HDFS文件系统中input目录下的Merge.txt学生信息文件输出到eclipse终端进行显示,这个文件是林君学长自己之前写好的!大家可以用上面上传的data.txt文件进行显示程序测试哦!

4、显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息;

1)、在eclipse中创建DisplayHdfsContent类,并写入实现该题目功能的java程序

package hdfsFileOperations;

import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.*;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class DisplayHdfsContent {
	//显示指定文件大小、权限、创建时间、权限等
	public void displayHdfsContent()throws IOException{
		String remote="/user/hadoop/input/Merge.txt";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		FileStatus[] status = fs.listStatus(new Path(remote));
		for(int i=0;i<status.length;i++){
			long time=status[i].getModificationTime();
			Date date = new Date(time);   
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String data = sdf.format(date);
			System.out.println("路径: " + status[i].getPath()+ "   文件大小: " + status[i].getLen() + "   权限: " + status[i].getPermission() + "  文件创建时间: "+data);
		}
	}
}

2)、java代码功能解释

以上的JAVA程序的主要功能是将HDFS文件系统下的input目录下列出Merge.txt的文件的基本信息!

5、给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息,如果该文件是目录,则递归输出该目录下所有文件相关信息

1)、创建类displayAllHdfsContent,并编写实现该功能的JAVA程序

package hdfsFileOperations;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.*;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class DisplayAllHdfsContent {
	//显示所有文件大小、权限、创建时间、权限等
	public void displayAllHdfsContent () throws IOException{
		String filePath="/user/hadoop/input/";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
        FileSystem fs = FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		FileStatus[] status = fs.listStatus(new Path(filePath));
		for(int i=0;i<status.length;i++){
			long time =status[i].getModificationTime();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = new Date(time);
			String data = format.format(date);
			System.out.println("文件大小为:"+status[i].getBlockSize()+"  文件路径为:"+status[i].getPath()+"   文件的权限为:"+status[i].getPermission()+"   文件创建时间:"+data);
		}
	}
}

2)、java代码功能解释

以上的JAVA程序的主要功能是列出HDFS文件系统下的input目录下所有文件的基本信息!

6、提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录

1)、创建类DeleteOrAddHdfs,并编写完成该功能的是java代码:

package hdfsFileOperations;
import java.net.URI;
import java.util.Scanner;
import java.io.*;

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 DeleteOrAddHdfs {
	//创建文件**
	public void deleteOrAddHdfs() throws IOException{
		System.out.println("1、创建文件");
		System.out.println("2、删除文件");
		System.out.println("3、退出!");
		System.out.print("请输入你的选择:");
		Scanner in = new Scanner(System.in);
		int a=in.nextInt();
		switch(a){
		case 1: mk();break;
		case 2: rm();break;
		case 3:break;
		}
	}
	public void mk() throws IOException{
		String upremote="/user/hadoop/input";
		String remote="/user/hadoop/input/myfile.txt";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs =FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path a = new Path(upremote);
		Path b = new Path(remote);
		if(!fs.exists(a))
		{
			System.out.println("该路径不存在,即将进行创建");
			fs.mkdirs(a);
			FSDataOutputStream out = fs.create(b);
			out.close();
			System.out.println("文件创建成功!");
		}else{
			System.out.println("该路径存在,即将创建目标文件");
			FSDataOutputStream out = fs.create(b);
			out.close();
			System.out.println("文件创建成功!");
		}
	}
	//删除文件,由用户指定删除目录不为空时,是否还进行删除
	public static void rm() throws IOException{
		String remote="/user/hadoop/input/myfile.txt";
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS","hdfs://localhost:9000");
        conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
		FileSystem fs =FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path a = new Path(remote);
		FileStatus[] status = fs.listStatus(a);
		if(status.length>0)
		{
			System.out.println("文件目录不为空,你可以做如下操作:");
			System.out.println("1、继续删除");
			System.out.println("2、不删除");
			System.out.print("请输入你的选择:");
			Scanner in = new Scanner(System.in);
			int x=in.nextInt();
		    if(x==1)
		    {
				fs.delete(a,true);
				System.out.println("目录已经删除");
		    }
			else if(x==2)
			{
				System.out.println("未做任何操作!");
			}	
		}
	}	
}

2)、java代码功能解释

在input路径下创建myfile.txt文件,显然,该路径存在,所以可以直接创建,然后我们也可以删除这个文件!

7、在HDFS中,将文件从源路径移动到目的路径

1)、创建类MoveHdfs,并编写完成该功能的是java代码:

package hdfsFileOperations;

import java.net.URI;
import java.io.*;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class MoveHdfs {
	//在hdfs中进行文件的移动
	public void moveHdfs() throws IOException{
		String prepath="/user/hadoop/input/Merge.txt";
		String newpath="/user/hadoop/file/";
		Configuration conf = new Configuration();
	    FileSystem fs =FileSystem.get(URI.create("hdfs://localhost:9000"),conf);
		Path a = new Path(prepath);
		Path b = new Path(newpath);
		if(fs.rename(a,b))
		{
			System.out.println("移动成功");
		}
	}
}

2)、java代码功能解释

以上是将input目录下的Merge.txt文件移动到,file文件目录下面!

8、JAVA编程对HDFS文件操作目录结构

1)、在包view下面创建Menu菜单类,并编写我们的菜单JAVA程序:

package view;
import java.io.IOException;
import java.util.Scanner;
import hdfsFileOperations.DeleteOrAddHdfs;
import hdfsFileOperations.DisplayAllHdfsContent;
import hdfsFileOperations.DisplayHdfsContent;
import hdfsFileOperations.DownloadHdfs;
import hdfsFileOperations.MoveHdfs;
import hdfsFileOperations.OutputHdfsTOTerminal;
import hdfsFileOperations.UploadHdfs;
//以下为对HDFS文件操作的目录
public class Menu {
	public static void main(String[] args) throws IOException{
		UploadHdfs h1=new UploadHdfs();
		DownloadHdfs h2=new DownloadHdfs();
		OutputHdfsTOTerminal h3=new OutputHdfsTOTerminal();
		DisplayHdfsContent h4=new DisplayHdfsContent();
		DisplayAllHdfsContent h5=new DisplayAllHdfsContent();
		DeleteOrAddHdfs h6=new DeleteOrAddHdfs();
		MoveHdfs h7=new MoveHdfs();
		Scanner input = new Scanner(System.in);
		while(true){
			System.out.println("**********************基于JAVA的HDFS文件操作**********************");
			System.out.println("1、向HDFS上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件");
			System.out.println("2、从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名");
			System.out.println("3、将HDFS中指定文件的内容输出到终端中");
			System.out.println("4、显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息");
			System.out.println("5、给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息,如果该文件是目录,则递归输出该目录下所有文件相关信息");
			System.out.println("6、提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录");
			System.out.println("7、在HDFS中,将文件从源路径移动到目的路径");
			System.out.println("0、退出!");
			System.out.print("请输入你的选择:");
			int a=input.nextInt();
			switch(a){
			case 1: h1.uploadFile();break;
			case 2: h2.download();break;
			case 3: h3.displayFile();break;
			case 4: h4.displayHdfsContent();break;
			case 5: h5.displayAllHdfsContent();break;
			case 6: h6.deleteOrAddHdfs();break;
			case 7: h7.moveHdfs();break;
			case 0:break;
			}
		}
	}
}

2)、程序说明:

该代码没有什么说明的,就是通过对其他几个功能类进行对象实例化操作,然后调用其中的功能函数,最后通过Switch
case语句进行相应的选择,已达到我们要求的功能!

三、项目运行结果显示

1、打开终端,切换用户,并运行hadoop

1)、打开ubuntu本地终端,切换hadoop用户

su - hadoop

2)、进入hadoop运行环境

cd /usr/local/hadoop

3)、运行hadoop

./sbin/start-hdfs.sh
jps

在这里插入图片描述

2、项目选择菜单运行结果

1)、终端目录的运行结果如下所示:
在这里插入图片描述

3、向HDFS上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件的运行结果

1)、eclipse终端运行结果:
在这里插入图片描述
因为目标路径没有data.txt文件,所以直接上传成功!
2)、再次运行,判断是否有该文件:
在这里插入图片描述
可以看到,已经存在,选择覆盖刚才的文件!
3)、通过终端cat命令,查看文件是否成功上传:
在这里插入图片描述
上图可知,文件已经上传成功了!
4)、与本地文件对比如下:
在这里插入图片描述
可以发现,内容一模一样哦!

4、从HDFS中下载指定文件,如果本地文件与要下载的文件名称相同,则自动对下载的文件重命名的运行结果

1)、eclipse终端运行结果:
在这里插入图片描述
上面我们可以知道,本地文件file文件夹下已经有了刚刚的文件,所以,我们需要重新命令为data1.txt
2)、在本地file文件中查看是否下载成功:
在这里插入图片描述
3)、查看data1.txt文件内容
在这里插入图片描述
上图可知,文件内容完整!

5、将HDFS中指定文件的内容输出到终端

1)、eclipse终端运行截图如下:
在这里插入图片描述
2)、在ubuntu本地终端查看文件内容是否和eclipse终端上面的一致
在这里插入图片描述
上图可以看出,完全一致,显示成功!

6、显示HDFS中指定的文件的读写权限、大小、创建时间、路径等信息运行结果

1)、在eclipse终端显示的结果如下所示:
在这里插入图片描述
可以看到,以上命令的执行效果已经将该文件的基本信息列举成功,并显示在eclipse控制台上面了哦!

7、给定HDFS中某一个目录,输出该目录下的所有文件的读写权限、大小、创建时间、路径等信息运行结果

1)、在eclipse终端显示的结果如下所示:
在这里插入图片描述
2)、由上图可以看出,该程序已经将上面input目录下所有文件的基本信息显示出来了哦!

8、提供一个HDFS内的文件的路径,对该文件进行创建和删除操作。如果文件所在目录不存在,则自动创建目录

1)、在eclipse终端显示的结果如下所示:
创建文件:
在这里插入图片描述
2)、通过ls命令查看文件是否创建成功:
在这里插入图片描述
上面的文件已经完成创建,接下来我们进行文件删除
3)、删除文件:
在这里插入图片描述
4、通过ls命令查看文件是否删除:
在这里插入图片描述
上面可以看出,文件已经删除成功!该功能实现!

9、在HDFS中,将文件从源路径移动到目的路径运行结果

1)、eclipse终端运行截图如下:
在这里插入图片描述
2)、通过ls命令分别查看input目录下的文件是否已经移除,file目录下时候已经具有该文件:
input目录下:
在这里插入图片描述
Merge.txt文件已经移除掉了哦!
file目录下:
在这里插入图片描述
由上图可以知道,Merge.txt文件已经移动到file文件目录下了!
以上就是本次博客的全部内容啦,创作本次博客真的不易,小伙伴们记得点赞啦,希望对本次博客的阅读,可以帮助小伙伴更好的理解JAVA如何对HDFS文件系统进行操作哦!遇到问题的小伙伴记得评论区留言,林君学长看到会为大家解答的,这个学长不太冷!
陈一月的又一天编程岁月^ _ ^

发布了69 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42451251/article/details/105266643