假设客户端应用程序使用FileSplit
对象来读取相应文件中的实际字节。Hadoop FileSplit reading
为了这样做,一个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
类用于,实施“界限”。
UPDATE
显然,调整是必要只用例一线LineRecordReader
类,超过分割的界限,以确保它读取完整的最后一行的一个。
关于此问题的更多详细信息,请参阅earlier question和MAPREDUCE-772的评论。
上面的代码不会搜索到-1,而是以-1开头,即前一个字节第一场之后每场比赛开始。当然,TextInputFormat使用的LineRecordReader正如你所说的那样工作,因为它总是读取至少多出一个字节,并且一直延续到行尾。也许-1是为了解决这个问题。 – PNS 2013-04-24 00:09:13
你能指点我的源/展示此-1寻求行为的示例 – 2013-04-24 00:25:13
第59行http://javasourcecode.org/html/open-source/hadoop/hadoop-1.0.3/org/apache/hadoop/mapreduce/ lib/input/LineRecordReader.java.html并不寻求开始 - 1 ... – 2013-04-24 00:27:30