HDFS源码笔记之FileSystem

FileSystem,顾名思义是一个实现了文件系统的抽象类,继承自org.apache.hadoop.conf.Configured,并实现了Closeable接口,可以适用于多种文件系统,如本地文件系统file://,ftp,hdfs等。如果要自己实现一个系统可以通过继承这个类(hadoop中DistributeFileSystem就是这样的),做相应的配置,并实现相应的抽象方法。



     
一、 静态管理对象 
FileSystem是一个具有一般文件系统特性的类。在hdfs中有多个管理对象用于管理不同的文件系统对应的信息。
1、cache机制
在FileSystem中有一个静态cache类,内含一个 final Map map(为了能够快速获取FileSystem,这个map采用的是HashMap),用于存储和管理由{scheme,authority,username}作为Key,而以FileSystem引用作为值的键值对。当给定uri调用get获取指定的FileSystem时,最终还是调用cache.get。cache.get会查找相应的键值对,不存在时调用createFileSystem新建一个FileSystem并将其插入map中。当本FS关闭时,要将CACHE中对应的键值对删除。
由于同一时刻可能要多个client请求访问map,所以需要对访问map的操作进行同步synchronized(这些都要保证是thread-safe)。
当关闭FS的时候(用户手动关闭或JVM在程序运行结束,ClientFinalizer对文件系统进行关闭),首先会调用cache的closeAll方法,对map进行清空(先清空cache中其他FS的键值对,再清空本FS的键值对);然后再调用FS的processDeleteOnExit方法对一些temp目录进行清空。
2、statisticsTable统计信息管理映射表
statisticsTable是一个IdentityHashMap, Statistics>,用于保存并管理每个文件系统对应的统计信息Statistics。
3、deleteOnExit临时文件集合
FileSystem中deleteOnExit用于保存所有需要在本FS关闭时或JVM退出时需要删掉的文件集合,通过调用processDeleteOnExit将这些路径进行清空。


二、文件系统的信息
1、Statistics类一个FileSystem的统计信息
由于要允许并行化处理,所以Statistics中定义了2个原子变量bytesRead(读的字节数)、bytesWritten(写的字节数)。每个文件系统在刚创建时会调用initialize(URI, Configuration)将自己的statistics添加到statisticsTable中。
2、FileStatus文件元数据类(目录也可以视为文件)
FileSystem中定义了FileStatus用于存放文件和目录的元数据(Permission,是否目录,长度、备份数、块大小、最近访问时间、最近修改时间、是否为目录)。可以getFileStatus获取指定的文件的FileStatus。同时在FileStatus中实现了org.apache.hadoop.io.Writable接口,是可序列化的(之所以需要序列化,是因为我们可以把FileStatus看成一个数据类型(hadoop中数据类型是需要进行序列化,因为要在网络中传输)--保存了文件的元数据)。
3、Key
这个类用于作为一个特定文件系统的标识,由(uri,username)构成。
4、文件块类BlockLocation
  private String[] hosts; //文件块所在的主机名
  private String[] names; //文件块所在的主机socket
  private String[] topologyPaths; // 文件块在网络拓扑中的完整路径
  private long offset;  //文件块在文件中的偏移位置
  private long length;//文件块的大小
基于备份冗余机制,一个文件块可能有多个备份,存放在不同的位置。
由于可以视为一个数据类型,故需要实现序列化




三、FileSystem各种用于操作文件的方法
1、创建文件方法create:
public abstract FSDataOutputStream create(Path f,
      FsPermission permission,//权限
      boolean overwrite,//是否覆盖
      int bufferSize,//用于写文件所需的缓存大小
      short replication,//备份数,默认情况下为1
      long blockSize,//块大小,默认为64MB
      Progressable progress);//进度函数,用于实时获取文件的写入进度
用于获取一个写入文件的输入流,只支持从文件末尾进行写入。
其中提供了多个create的重载函数。
值得注意的是这个函数返回的是一个输出流FSDataOutputStream(用于将本地的输出到FS(FileSystem,下同)(即FileSystem)上),这个流继承自DataOutputStream,可以对文件进行写入。同时其内部还包含了一个静态类PositionCache(用于保存一个文件的已写入数据的统计类和写入的位置)。
2、读取文件的内容方法open:
public abstract FSDataInputStream open(Path f, int bufferSize)throws IOException;
FileSystem的open方法返回一个FSDataInputStream,实现了Seekable、PositionedReadable这两个接口,支持随机访问读取文件,可以通过指定开始读取的位置(权威指南上说seek实现开销比较大,慎用)。
3、目录创建mkdirs
可以指定文件的权限或使用默认的路径。对于指定的path,会创建不存在的父目录(可以用exits来判断路径是否存在)。
4、文件的复制、移动()
FileSystem中有两种复制:copyFromLocalFile和copyToLocalFile。
文件的移动可以看成是文件的复制再将源文件删除。故FileSystem中存在两种相应的文件移动操作moveFromLocalFile和moveToLocalFile






四、抽象方法(基本的文件操作方法)
不同的文件系统有不同的特性。在FileSystem中有多个抽象方法需要继承这个类时根据其功能进行实现:
1、public abstract URI getUri();//获取本文件系统的uri
2、public abstract FSDataInputStream open(Path f, int bufferSize)//读出一个文件的数据时调用
3、public abstract FSDataOutputStream create//写入文件的数据时调用
4、 public abstract FSDataOutputStream append//在文件末尾添加数据
5、public abstract boolean rename//文件重命名
6、public abstract boolean delete//删除一个文件或目录
7、 public abstract FileStatus[] listStatus//列出路径下对应的文件集
8、public abstract void setWorkingDirectory//设置工作目录
   public abstract Path getWorkingDirectory()
9、public abstract boolean mkdirs//创建一个目录
10、  public abstract FileStatus getFileStatus//获取文件或目录的元数据


你可能感兴趣的:(Hadoop笔记)