FileSplit
対応するファイルから実際のバイトを読み取るためにオブジェクトを使用するクライアント アプリケーションを想定します。
そのためには、次のようなコードを使用InputStream
して からオブジェクトを作成する必要があります。FileSplit
FileSplit split = ... // The FileSplit reference
FileSystem fs = ... // The HDFS reference
FSDataInputStream fsin = fs.open(split.getPath());
long start = split.getStart()-1; // Byte before the first
if (start >= 0)
{
fsin.seek(start);
}
-1 によるストリームの調整は、Hadoop
MapReduce
LineRecordReader
クラスなどのいくつかのシナリオに存在します。ただし、FSDataInputStream
seek()
メソッドのドキュメントには、特定の場所をシークした後、次の読み取りはその場所から行われることが明示的に示されています。これは、上記のコードが 1 バイトずれている (?) ことを意味します (?)。
問題は、すべての InputSplit 読み取りケースで「-1」の調整が必要かどうかです。
ところで、FileSplit
正しく読みたい場合は、その開始点までシークするだけでは十分ではありません。これは、すべての分割にも、実際の HDFS ファイルの終了点とは異なる終了点がある可能性があるためです。したがって、対応するInputStream
ものは「制限」されている必要があります。つまり、次のように最大長があります。
InputStream is = new BoundedInputStream(fsin, split.getLength());
この場合、fsin
上で「ネイティブ」ストリームを作成した後、org.apache.commons.io.input.BoundedInputStream
クラスを使用して「境界」を実装します。
アップデート
どうやら調整は、LineRecordReader
最後の行全体を確実に読み取るために分割の境界を超えるクラスの 1 つのユース ケースにのみ必要です。
これに関するより詳細な議論は、以前の質問とMAPREDUCE-772のコメントにあります。