一、FSDataInputStream
FileSystem中的open()方法实际上返回的是一个FSDataInputStream,而不是标准的java.io类。这个类是java.io.DataInputStream
的一个子类,支持随机访问,这样就可以从流的任何位置读取数据了
public class FSDataInputStream extends DataInputStream
implements Seekable, PositionedReadable,
ByteBufferReadable, HasFileDescriptor, CanSetDropBehind, CanSetReadahead,
HasEnhancedByteBufferAccess {。。。。。}
Seekable接口允许在文件中定位,并提供一个查询方法,用于查询当前位置相对于文件开始处的偏移量(getpos())
public interfence Seekable{
void seek(long pos) throws IOException;
long getPos() throws IOException;
boolean seekToNewSource(long targetPos) throws IOException;
}
调用seek() 来定位大于文件长度的位置会导致IOException异常。与java.io.InputStream 中的skip() 不同,seek()并
没有指出数据流当前位置之后的一点,它可以移到文件中任意一个绝对位置。
应用程序开发人员并不常用seekToNewSource()方法。此方法一般倾向于切换到数据的另一个副本并在新的副本中寻找targetPos指定的位置。
HDFS内部就采用这样的方法在数据节点故障时为客户端提供可靠的数据输入流。
FSDataInputStream也实现了PositionedReadable接口,从一个指定位置读取一部分数据
二、FSDataOutputStream
Hadoop 的FileSystem中的create()方法返回了一个FSDataOutputStream,与FSDataInputStream类似,
它也有一个查询文件当前位置的方法:
public class FSDataOutputStream extends DataOutputStream
implements Syncable, CanSetDropBehind {
............
...........
public long getPos() throws IOException {
return position; // return cached position
}
}
但是,与FSDataInputStream不同,FSDataOutputStream不允许定位。这是因为HDFS只允许对一个打开的文件
顺序写入,或向一个已有文件添加。换句话说,它不支持文件尾部的其他位置的写入,这样一来,写入时的定位就没有什么意义。
-------------------引自Hadoop权威指南第三版