一、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權威指南第三版