读
FileSystem fileSystem = FileSystem.get(new Configuration());
FSDataInputStream fsDataInputStream = fileSystem.open(fileStatus.getPath());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fsDataInputStream));
1、调用FileSystem的open方法,根据继承关系实际调用到DistributedFileSystem的open方法,这一步和后一步实际是为获取信息。
2、DFSClient向NameNode请求block位置信息,NameNode返回的block位置信息按照网络拓扑距离由近到远排序,流包装为DFSInputStream。
3、DFSClient根据NameNode返回的信息和DataNode建立连接并打开DataInputStream输入流供读取。
4、客户端和DataNode进行交互,持续按块读取输入流直到读取完成。
open的调用关系
在我们使用的时候,只需要上边两行代码即可,实际执行时的调用过程如下
org.apache.hadoop.fs.FileSystem ---> open()
然后调用到DistributedFileSystem的open实现
public FSDataInputStream open(Path f, final int bufferSize)
throws IOException {
statistics.incrementReadOps(1);
Path absF = fixRelativePart(f);
return new FileSystemLinkResolver<FSDataInputStream>() {
@Override
public FSDataInputStream doCall(final Path p)
throws IOException, UnresolvedLinkException {
// 这里的dfs是一个DFSClient客户端,也就是说由一个DFS客户端来执行打开操作
final DFSInputStream dfsis =
dfs.open(getPathName(p), bufferSize, verifyChecksum);
// 一个DFSInputStream的包装流
return dfs.createWrappedInputStream(dfsis);
}
@Override
public FSDataInputStream next(final FileSystem fs, final Path p)
throws IOException {
return fs.open(p, bufferSize);
}
}.resolve(this, absF)