首页 > 代码库 > 2.HDFS操作

2.HDFS操作

1. 使用命令行操作
 1)4个通用命令行
  <1>archive 归档文件的创建
  用途:
    由于hadoop的设计是为了处理大数据,理想的数据应该blocksize的倍数。namenode在启动时会将所有的元数据load到内存中
   当大量小于blocksize的文件存在的时候,,不仅占用了大量的存储空间,也占用了大量的namenode内存。
   archive可以将多个小文件打包成一个大文件进行存储,并且打包后的文件仍然可以通过mapreduce来操作,因为
   打包后的文件由索引和存储两大部分组成,索引部分记录了原有的目录结构和文件状态。
  用法:
   hadoop archive -archiveName test.har -p /A/B /E/F /G/G1 /home
   -archiveName test.har表示指定归档文件的名称(har为后缀名),-p指定要打包文件的路径,可以有多个,
   最后的参数表示归档文件放在哪(相对路径)
  示例:
   hadoop archive -archiveName ins.har -p hdfs://192.168.80.11:9000/user.hadoop/in in
   运行发现,也是用的mapreduce
  <2>distcp 分布式复制
  用途:
   在相同的文件系统中并行的复制文件,且必须是相同版本。
   如果版本不一致,使用hdfs会产生错误,因为rpc不兼容,这时候可以使用基于HTTP协议的hftp协议,
   但目标仍然得是hdfs的:
   hadoop distcp hftp://namenode:50070/user/hadoop/input hdfs://namenode:9000/user/hadoop/input1
   也可使用webhdfs,源地址和目标地址都可以使用webhdfs,可以完全兼容
   hadoop distcp webhdfs://namenode:50070/user/hadoop/input webhdfs://namenode:50070/user/hadoop/input1 
  用法:
   hadoop distcp hdfs://namenode1/foo hdfs://namenode2/bar
   把第一个集群中的foo目录中的内容复制到第二个集群的bar目录下,如果bar不存在,则会新建一个。
   可以指定多个源路径,源路径必须是绝对路径。
   默认情况下,distcp会跳过目标路径已经存在的文件,但可以通过-overwrite选项进行覆盖,
   也可以使用-updata来选择只更新哪些修改过的文件。
   distcp会将一大堆文件平均分摊开交给map去执行,每个文件单独一个map。如果总大小小于256M,
   distcp只会分配一个map。但如果平分的结果出现map和超过20的情况,每个节点的map数就会按20算。
   可以使用-m讲maps设置的大一些。
   <3>jar
   用途:
    运行一个内含hadoop运行代码的jar文件
   示例:
    hadoop jar jar包名字 主类方法 参数
    如:
    hadoop jar sample.jar mainmethod args
   <4>fs
   用途:
    运行一个常规的文件基本命令
    
    
  2)18个常用的基本命令的操作
   格式为:hadoop fs -cmd <agrs>,可以使用hadoop fs -help来获取帮助
   <1>-cat
   用途: 将路经指定的文件输出到屏幕
   示例: hadoop fs -cat URI
   <2>-copyFromLocal
   用途: 将本地文件复制到HDFS中
   示例:hadoop fs -copyFromLocal localURI
   <3>-copyToLocal
   用途:将一个文件从HDFS中复制到本地文件
   示例:hadoop fs -copyToLocal localURI
   <4>-cp
   用途:将文件从原路径复制到目标路径,原路径可以有多个,目标路径只有一个
   示例:
   hadoop fs -cp /user/file /user/files
   hadoop fs -cp /user/file1 /user/file2 /user/files
   <5>-du
   用途:不指定具体文件只指定目录时,显示目录下文各件的大小;指定了某个具体目录,显示该目录下所有文件的大小
      什么都不指定时,显示HDFS所有文件大小
   示例:hadoop fs -du URI
   <6>-dus
   用途:显示目标文件或者目录的大小
   示例:hadoop fs -dus 或者
   hadoop fs -dus hdfs://master:9000/user/hadoop/in
   <7>-expunge
   用途:清空回收站
   示例:hadoop fs -expunge
   <8>-get
   用途:复制文件到本地文件系统
   示例:hadoop fs -get hdfs://master:9000/user/hadoop/in/ins /home/hadoop/
   <9>-ls
   用途:遍历,如果是一个目录,返回其子文件的一个列表
   示例:hadoop fs -ls返回文件相同中的所有文件夹列表
   hadoop fs -ls hdfs://master:9000/user/hadoop/in返回in文件夹下所有文件和文件夹
   <10>-lsr
   用途:递归的查阅文件
   示例:hadoop fs -lsr展示文件系统中所有的文件列表
   <11>-mkdir
   用途:创建文件夹,如果父母路不存在,则一起创建父目录
   示例:hadoop fs -mkdir hdfs://master:9000/user/hadopp/in2
   <12>-mv
   用途:同一个文件系统中移动文件,目标可以有多个
   示例:hadoop fs -mv src target
   <13>-put
   用途:从本地文件系统复制单个或者多个路径到目标文件系统
   示例:hadoop fs -put localfile hdfs://master:9000/user/hadoop/in
   hadoop fs -put /home/hadoop/jdk1.6.0_24/ hdfs://master:9000/user/hadoop/in
   <14>-rm
   用途:删除指定的文件,要求非空的目录和文件
   示例:hadoop fs -rm URI
   <15>-rmr
   用途:递归的删除指定目录及其子文件
   示例:hadoop fs -rmr URI
   <16>-setrep
   用途:改变一个文件副本数
   示例:hadoop fs -setrep -w 3 -R hdfs://master:9000/uer/hadoop/in/ins
   <17>-test
   用途:使用ezd对文件进行检查
   示例:-e检查文件是否存在,若存在返回0
      -z检查文件是否是0字节,如果是,返回0
      -d检查路径是否是目录,是返回1,否返回0
   <18>-text
   用途:将原文件输出为文本格式,运行格式为zip或者Text类
   示例:hadoop fs -text srcfile
   
   *上述HDFS中的文件路径可以直接写/user/hadoop/in/ins,省略前面的hdfs://192.68.80.11:9000,
   因为已经在core-site.xml中定义过了。
   
2.使用web浏览器浏览HDFS文件
 浏览器输入http://192.168.80.11:50070即可查看HDFS的相关信息和日志
 
3.使用FileSystem API来操作HDFS文件
 1)读取HDFS上的数据
 

 import java.io.IOException;

  import java.net.URI;

  

  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 Hdfsoper1 {

   public static void main(String[] args) throws IOException {

    Configuration conf = new Configuration();

    String path = "hdfs://192.168.80.11:9000/user/hadoop/in/ins";

    FileSystem fs = FileSystem.get(URI.create(path), conf);

    

    FSDataInputStream fsin = fs.open(new Path(path));

    

    IOUtils.copyBytes(fsin, System.out, 1024);

    

   }

  }

  2)有选择的读取,即可以自己设置读取位置
 

 import java.io.IOException;

  import java.net.URI;

  

  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;

  

  /**

   * 可以通过seek()方法设置读取的位置

   */

  public class hdfsoper2 {

   public static void main(String[] args) throws IOException {

    Configuration conf=  new Configuration();

    String path = "hdfs://192.168.80.11:9000/user/hadoop/in/ins";

    FileSystem fs = FileSystem.get(URI.create(path), conf);

    FSDataInputStream fsin = fs.open(new Path(path));

    IOUtils.copyBytes(fsin, System.out, 1024);

    fsin.seek(18);

    System.out.println("*********read again**********");

    IOUtils.copyBytes(fsin, System.out, 1024);

   }

  }

  3)上传本地文件到HDFS中

  import java.io.BufferedInputStream;

  import java.io.FileInputStream;

  import java.io.IOException;

  import java.io.InputStream;

  import java.io.OutputStream;

  import java.net.URI;

  import org.apache.hadoop.conf.Configuration;

  import org.apache.hadoop.fs.FileSystem;

  import org.apache.hadoop.fs.Path;

  import org.apache.hadoop.io.IOUtils;

  import org.apache.hadoop.util.Progressable;

  /**

   * upload file to HDFS

   */

  public class Hdfsoper3 {

   public static void main(String[] args) throws IOException {

    Configuration conf = new Configuration();

    //source file

    String source = "/home/hadoop/jdk-6u24-linux-i586.bin";

    InputStream in = new BufferedInputStream(new FileInputStream(source));

    //target file

    String target = "hdfs://192.168.80.11:9000/user/hadoop/in/jdk.bin";

    

    FileSystem fs = FileSystem.get(URI.create(target), conf);

    OutputStream out = fs.create(new Path(target), new Progressable() {

     @Override

     //when upload 64KB to hdfs, then print a * in the console

     public void progress() {

      System.out.print("*");

     }

    });

    

    IOUtils.copyBytes(in, out, 4096, true);

   }

  }

  4)删除HDFS中的文件

  import java.io.IOException;

  import java.net.URI;

  import org.apache.hadoop.conf.Configuration;

  import org.apache.hadoop.fs.FileSystem;

  import org.apache.hadoop.fs.Path;

  /**

   * delete file by FileSystem.delete( new Path(), true);

   */

  public class hdfsoper4 {

   public static void main(String[] args) throws IOException {

    Configuration conf = new Configuration();

    

    String path = "hdfs://192.168.80.11:9000/user/hadoop/in/jdk.bin";

    

    FileSystem fs = FileSystem.get(URI.create(path), conf);

    

    //if we want delete a directory, then true

    fs.delete(new Path(path), true);

   }

  }

本文出自 “积水成渊” 博客,请务必保留此出处http://xiaochu.blog.51cto.com/1048262/1436715