1)、整体项目的目录截图如下:
其中src源代码包可以不用看,主要功能在hdfs和view包中的class文件
1)、在文件包view包下面菜单类的讲解
有上面项目图可以看出,我们选择文件的菜单主要是通过Menu进行菜单选择,该java文件中包含了菜单选择的功能!
2)、在文件包hdfsFile包下面的功能文件的讲解
该系统目录中各个类的功能如下所示:
1)、ubuntu本地的文件数据
在ubuntu本地文件,自己找到对应的位置,新建几个txt文件,为后面的文件操作做准备,比如,林君学长的数据如下:
分别对应的文件内容如下所示:
2)、HDFS中的文件数据
当然,自己在HDFS相关文件夹下也应该创建一下相应的文件,这里就不再教大家如何利用shell命令创建文件了,大家可以去林君学长之前写的Hdfs与shell命令的交互博客下去查看哦!林君学长路径下的文件如下:
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目录下去,如果文件存在,则由我们觉得是覆盖文件还是添加到文件尾部!
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文件夹下面去
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文件进行显示程序测试哦!
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的文件的基本信息!
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目录下所有文件的基本信息!
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文件,显然,该路径存在,所以可以直接创建,然后我们也可以删除这个文件!
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文件目录下面!
1)、创建类ReadLine,并编写完成该功能的是java代码:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
public class ReadLine {
public class MyFSDataInputStream extends FSDataInputStream {
public MyFSDataInputStream(InputStream in) {
super(in);
// TODO Auto-generated constructor stub
}
}
public String readline() throws IOException {
String remoteFilePath="/user/hadoop/input/data.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 remotePath = new Path(remoteFilePath);
FSDataInputStream in = fs.open(remotePath);
BufferedReader d = new BufferedReader(new InputStreamReader(in));
String line = null;
String a="未读取到文件尾";
if ((line = d.readLine()) != null) {
d.close();
in.close();
return line;
}
return a;
}
}
2)、java代码功能解释
以上是将input目录下的data.txt文件进行读取!
1)、创建类DisplayTheContent,并编写完成该功能的是java代码:
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class DisplayTheContent {
private String remotePath="/user/hadoop/input/data.txt";
public void show(){
try {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
InputStream inputStream = new URL("hdfs","localhost",9000,remotePath.toString()).openStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2)、java代码功能解释
以上是将input目录下的data.txt显示到eclipse的终端
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();
ReadLine h8=new ReadLine();
DisplayTheContent h9=new DisplayTheContent();
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("8、实现按行读取HDFS中指定文件的方法“readLine()”,如果读到文件末尾,则返回空,否则返回文件一行的文本");
System.out.println("9、用”java.net.URL”和“org.apache.hadoop.fs.FsURLStreamHandlerFactory”编程完成输出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 8: h8.readline();break;
case 9: h9.show();break;
case 0:break;
}
}
}
}
2)、程序说明:
该代码没有什么说明的,就是通过对其他几个功能类进行对象实例化操作,然后调用其中的功能函数,最后通过Switch
case语句进行相应的选择,已达到我们要求的功能!
1)、打开ubuntu本地终端,切换hadoop用户
su - hadoop
2)、进入hadoop运行环境
cd /usr/local/hadoop
3)、运行hadoop
./sbin/start-hdfs.sh
jps
1)、eclipse终端运行结果:
因为目标路径没有data.txt文件,所以直接上传成功!
2)、再次运行,判断是否有该文件:
可以看到,已经存在,选择覆盖刚才的文件!
3)、通过终端cat命令,查看文件是否成功上传:
上图可知,文件已经上传成功了!
4)、与本地文件对比如下:
可以发现,内容一模一样哦!
1)、eclipse终端运行结果:
上面我们可以知道,本地文件file文件夹下已经有了刚刚的文件,所以,我们需要重新命令为data1.txt
2)、在本地file文件中查看是否下载成功:
3)、查看data1.txt文件内容
上图可知,文件内容完整!
1)、eclipse终端运行截图如下:
2)、在ubuntu本地终端查看文件内容是否和eclipse终端上面的一致
上图可以看出,完全一致,显示成功!
1)、在eclipse终端显示的结果如下所示:
可以看到,以上命令的执行效果已经将该文件的基本信息列举成功,并显示在eclipse控制台上面了哦!
1)、在eclipse终端显示的结果如下所示:
2)、由上图可以看出,该程序已经将上面input目录下所有文件的基本信息显示出来了哦!
1)、在eclipse终端显示的结果如下所示:
创建文件:
2)、通过ls命令查看文件是否创建成功:
上面的文件已经完成创建,接下来我们进行文件删除
3)、删除文件:
4、通过ls命令查看文件是否删除:
上面可以看出,文件已经删除成功!该功能实现!
1)、eclipse终端运行截图如下:
2)、通过ls命令分别查看input目录下的文件是否已经移除,file目录下时候已经具有该文件:
input目录下:
Merge.txt文件已经移除掉了哦!
file目录下:
由上图可以知道,Merge.txt文件已经移动到file文件目录下了!
1)、eclipse的运行结果:
上面可以看出,返回为空,说明文件读取到文件尾了哦!
1)、eclipse终端运行结果:
2)、利用cat命令查看是否与原内容一致
./bin/hdfs dfs -cat /user/hadoop/input/data.txt
上图对比看出,文件内容一模一样,说明显示到终端成功!
以上就是本次博客的全部内容啦,创作本次博客真的不易,小伙伴们记得点赞啦,希望对本次博客的阅读,可以帮助小伙伴更好的理解JAVA如何对HDFS文件系统进行操作哦!遇到问题的小伙伴记得评论区留言,林君学长看到会为大家解答的,这个学长不太冷!
陈一月的又一天编程岁月^ _ ^