Hadoop權威指南:FSDataInputStream對象
FileSystem對象中的open()方法返回的是FSDataInputStream對象, 而不是標准的java.io類對象,這個類是繼承了java.io.DataInputStream接口的一個特殊類,並支持隨機訪問,可以從流中的任意位置讀取數據
package org.apache.hadoop.fs;
public class FSDataInputStream extends DataInputStream implements Seekable, PositionedReadable {
// implementation elided
}
Seekable接口支持在文件中找到指定位置,並提供一個查詢當前位置相對於文件起始位置偏移量的查詢方法(getPos())
public interface Seekable {
void seek(long pos) throws IOExcption;
long getPos() throws IOException;
boolean seekToNewSource(long targetPos) throws IOException;
}
**與java.io.InputStream的skip()不同,seek()可以移動到文件中任意一個絕對位置,skip()則只能相對於當前位置定位到另一個新位置.
使用seek()方法,將Hadoop文件系統中的一個文件寫入標准輸出兩次
代碼
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import java.io.IOException;
import java.net.URI;
public class FileSystemDoubleCat {
public static void main(String[] args) throws IOException {
String uri = args[0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
FSDataInputStream in = null;
try {
in = fs.open(new Path(uri));
IOUtils.copyBytes(in, System.out, 4096, false);
in.seek(0);
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}
編譯
javac FileSystemDoubleCat
運行
hadoop FileSystemDoubleCat hdfs://localhost/user/hadoop/in
PositionedReadable接口
FSDataInputStream類也實現了PositionedReadable接口,從一個指定偏移量處讀取文件的一部分
public interfacen PositionedReadable {
public int read(long position, byte[] buffer, int offset, int length) throws IOExcption;
public void readFully(long position, byte[] buffer, int offset, int length) throws IOExcption;
public void readFully(long position, byte[] buffer) throws IOExcption;
}
read()
read()方法從文件的指定position處讀取之多為length字節的數據並存入緩沖區buffer的指定偏移量offset處.
返回值是實際讀到的數據的字節數 可能小於指定的length長度
readFully()
readFully()方法將指定length長度的字節數據讀取到buffer中(或在只接受buffer字節數組的版本種)
讀取到文件末尾會拋出EOFException異常
