HDFS shell操作及JAVA编程

Posted by Zreal on May 10, 2019

HDFS shell操作及JAVA编程

author:曾令泽

学号:1120162062

平台:MAC OS

[TOC]

hadoop shell命令操作hdfs

给定目录,列出文件信息

1
$ hadoop fs -ls -R -h {dir}

其中

-ls 代表列出文件信息命令

-R 参数代表该目录下所有的文件及文件夹

-h 参数代表文件的权限,文件名,最近一次修改时间等信息

img

指定文件内容输出到终端

1
$ hadoop fs -cat {filepath}

其中

-cat 代表打印文件内容命令

img

向hdfs上传文件

追加文件到指定文件后

1
$ hadoop fs -appendToFile {local_file} {src_file}

将文件从本地上传到hdfs(hdfs上不存在同名文件,拷贝地址为文件夹地址)

1
$ hadoop fs -put {local_file} {src_dir}

将文件从本地上传到hdfs (加上参数-f即可覆盖)

1
$ hadoop fs -copyFromLocal -f {local_file} {src_file}

img

将文件从hdfs下载到本地

将文件从hdfs下载到本地文件夹(文件夹下不存在同名文件)

1
$ hadoop fs -get {hdfs_file} {local_dir}

将文件从hdfs copy到本地文件

1
$ hadoop fs -copyToLocal {hdfs_file} {local_file}

img

将文件在hdfs上删除

1
$ hadoop fs -rm {hdfs_file}

img

Hadoop JAVA 编程

JAVA 初始化hadoop配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  static FileSystem hdfs;
   static Configuration conf=new Configuration();


    static String locpath="hdfs://localhost:9000";

    static {
        try {
            conf.set("dfs.replication","1");
            conf.set("fs.defaultFS","hdfs://localhost:9000");
            hdfs = FileSystem.get(conf);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

将本地文件上传到HDFS上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
hdfs上 文件是否存在
*/
public static boolean existFile(String fileName) throws  Exception{
        Path f=new Path(fileName);
        return hdfs.exists(f);
}


/*

拷贝文件到hdfs,如果hdfs中存在同名文件, 可选择覆盖或者追加

*/


public static void copyFile(String localSrc,String dst,Configuration conf)throws Exception
{
            File file=new File(localSrc);
            dst=locpath+dst;
            Path p=new Path(dst);
            FSDataOutputStream output=null;
            if(!existFile(dst)){
                InputStream in=new BufferedInputStream(new FileInputStream(file));
                OutputStream out= hdfs.create(p);
                IOUtils.copyBytes(in,out,4096,true);
                in.close();
                System.out.println("put the file"+localSrc+"to the hdfs"+dst);
            }
            else{
                System.out.println("file exists , would you want to  append write it or override it");
                System.out.print("please input 1 or 2");
                Scanner sc=new Scanner(System.in);
                int c=sc.nextInt();
                // 追加
                if(c==1){
                    InputStream in=new BufferedInputStream(new FileInputStream(file));
                    output=hdfs.append(p);
                    IOUtils.copyBytes(in,output,4096,true);
                    in.close();
                    output.close();
                    System.out.println(" the append is finished");
                }
                // 重写
                else{
                    InputStream in=new BufferedInputStream(new FileInputStream(file));
                    try{hdfs.delete(p,true);}
                    catch (Exception e){
                        e.printStackTrace();
                    }
                    output=hdfs.create(p);
                    IOUtils.copyBytes(in,output,4096,true);
                    in.close();
                    output.close();
                    System.out.println("the overwrite is finished");
                }

            }

  }
  
/*
	put模块功能测试
*/

private static void test_put(a test){
         String src="/Users/e1ixir/k.txt";
         String des="/k_put.txt";
         try {
             a.copyFile(src, des, conf);
         }catch (Exception e){
             e.printStackTrace();
         }
    }

测试结果:

文件成功上传hdfs

IDEA 结果显示 上传到k2_put.txt文件

img

Hadoop显示

img

文件上传hdfs,重写

IDEA 结果显示

img

hadoop 上结果显示

img

文件上传到hdfs,追加

(该功能出现bug,还未解决,错误信息如下)

img

使用命令行发现一个不同:

img

可以看到颜色圈出来的地方代表的是DATANODE节点数,其中紫色的文件是我用IDEAJAVA,put上去的文件,他的副本节点数为3,而橙色圈出来的是我用hadoop shell 命令put上去的文件,他的副本节点为1。所以在append在线文件时,会因为副本节点不匹配而报错。

img

如何去设置副本节点的数量?

在IDEA中会自动将hadoop的副本节点设置为3,通过下面的方式进行设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//    static FileSystem hdfs;
//    static Configuration conf=new Configuration();
//
//
//    static String locpath="hdfs://localhost:9000";
//
//    static {
//        try {
//            conf.set("fs.defaultFS","hdfs://localhost:9000");
            conf.set("dfs.replication","1");
//            hdfs = FileSystem.get(conf);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

重新进行运行后,结果如下:

IDEA结果:

img

命令行结果:

img

可以看到成功进行了追加

将HDFS的文件copy到本地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
将hdfs文件copy到本地,如果本地文件有重名,随机生成字符串后缀储存。
*/

public static void FileToLocal(String localsdst,String hdfs_src,Configuration conf)throws Exception{
         Path p= new Path(hdfs_src);
         File f=new File(localsdst);
         FSDataInputStream in=hdfs.open(new Path(hdfs_src));
         //不存在,则无需改名,直接复制
         if(!f.exists()) {
             OutputStream out=new BufferedOutputStream(new FileOutputStream(f));
             IOUtils.copyBytes(in,out,4096,true);
             in.close();
             out.close();
             System.out.println("get the file "+hdfs_src+" to the local "+localsdst);
         }
         //改名添加
         else{
             File file=f;
             String rs=null;
             while(file.exists()) {
                 String random=GenerateRandomString();
                 String tmp=localsdst.split("\\.")[0];
                 String tail=localsdst.split("\\.")[1];
                 rs = tmp+"_"+random+"."+tail;
                 file = new File(rs);
             }
             file.createNewFile();
             OutputStream out=new BufferedOutputStream(new FileOutputStream(f));
             IOUtils.copyBytes(in,out,4096,true);
             in.close();
             out.close();
             System.out.print("rename :");
             System.out.println("get the file "+hdfs_src+" to the local "+rs);
         }

     }

/*
随机生成8位字符串
*/
private static String GenerateRandomString(){
         String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
         Random r=new Random();
         StringBuffer sb=new StringBuffer();
         for(int i=0;i<8;i++){
             int n=r.nextInt(62);
             sb.append(str.charAt(n));

         }
         return sb.toString();
}

/*
get 模块功能测试
*/
private static void test_get(a test){
         String src="/test_get.txt";
         String des="/Users/e1ixir/test_get_out.txt";
         try{
             a.FileToLocal(des,src,conf);
         }catch (Exception e){
             e.printStackTrace();
         }
    }

测试结果:

从hdfs下载文件到本地,无同名文件

IDEA结果显示

img

命令行本地结果

img

从hdfs下载文件到本地,需重命名

IDEA结果显示:

img

命令行本地结果显示:

img