文章目录
HDFS常见操作
代码基本结构
- Configuration:Hadoop配置信息
- FileSystem:文件系统
- hdfs.listStatus:文件状态,通过它调用文件系统
HDFS文件操作
上传文件到集群
- hdfs.copyFromLocalFile(new Path(srcLinux),new Path(desHDFS));
下载文件到Linux文件系统
- hdfs.copuToLocalFile(false,new Path(srcHDFS),new Path(desLinux) );
读取文件
- IOUtils.copyBytes(in,System.out,conf,true);//in:文件输入流InputStream,System.out:标准输出到Console上,true:关闭数据流,conf:Hadoop配置
HDFS的目录操作
重命名
- hdfs.rename(src,des)
创建目录
- hdfs.mkdirs(new Path(newDir));
判断文件是否存在
- hdfs.exists(file);
删除文件
- hdfs.delete(file,false);
查看HDFS基本信息
查看文件列表
-
file.getPath();
查看文件状态
- file.getModificationTime();
- file.getOwner();
- …
- 文件状态都通过listStatus方法保存在FileStatus里面,相应的状态可以通过访问官方Api文档获取
查看文件位置
- hdfs.getFileBlockLocations(fileStatus,0,fileStatus.getLen());
- block:块的信息
- host:主机名
查看节点信息
- DistributedFileSystem强制转换
- hdfs.getDataNodeStats()
压缩和解压缩
常见压缩方式
压缩
- Class<?> codecClass = Class.forName(“org.apache.hadoop.io.compress.GzipCodec”);
指定压缩方式类 - CompressionCodec codec = (CompressionCodec_ReflectionUtils.newInstance(codecCLass,conf);
实例化一个压缩对象
注意:如果想输出压缩文件里面的内容如果使用hadoop fs -cat 会产生乱码,这是需要把压缩文件以文本的形式输出:hadoop fs -text.
解压缩
- 使用方法和压缩过程一样,只是将in和out调换了位置
HDFS的系列化操作
SequenceFile
-
在存储结构上,SequenceFile主要由一个Header后跟多条Record组成每条Record以键值对的方式进行存储.
-
用来表示Record的字符数组可依次解析成:记录的长度、Key的长度、Key值和Value值,并且Value值的结构取决于该记录是否被压缩。
-
用hadoop fs -cat 可以得到头部信息:Header主要包含了Key classname,Value classname,存储压缩算法,用户自定义元数据等信息,此外,还包含了一些同步标识,用于快速定位到记录的边界。
写SequenceFile
- SequenceFile.Writer writer = SequenceFile.createWriter(hdfs,conf,src,IntWritable.Class,Text.class)
- writer.append(key,value);
读SequenceFIle
- SequenceFile.Reader reader=null;
- reader = new SequenceFile.Reader(hdfs,src,conf);
- long position = reader.getPosition();
MapFile
-
MapFile是排序后的SequenceFile,通过观察其目录结构可以看到MapFile由两部分组成,分别是data和index。
-
data记录了文件的内容
-
index作为文件的数据索引,主要记录了每个Record的key值,以及该Record在文件中的偏移位置(索引)。在MapFile被访问的时候,索引文件会被加载到内存,通过索引映射关系可迅速定位到指定Record所在文件位置,因此,相对SequenceFile而言,MapFile的检索效率是高效的,缺点是会消耗一部分内存来存储index数据。
-
通过MapFIle.Writer的setIndexInterval()方法,可以确定存入内存的间隔;
writer.setIndexInterval(1)表示隔一条便索引一次。当文件过大时,可以设置为更大的间隔
写MapFile
- MapFIle.Writer writer = new MapFile.Writer(conf,hdfs,des,IntWritable.class,Text.class);
- wirter.append(key,value);
读MapFile
- MapFile.Reader reader = new MapFile.Reader(hdfs,src,conf);
注意:使用MapFile或SequenceFile虽然可以解决HDFS中小文件的存储问题,但也有一定局限性,如:
- 文件不支持复写操作,不能向已存在的SequenceFile(MapFile)追加存储记录
- 当write流不关闭的时候,没有办法构造read流。也就是在执行文件写操作的时候,该文件是不可读取的