【发布时间】:2013-04-23 22:17:36
【问题描述】:
假设客户端应用程序使用FileSplit 对象从相应文件中读取实际字节。
为此,必须通过以下代码从FileSplit 创建一个InputStream 对象:
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);
}
在Hadoop MapReduce LineRecordReader 类等某些场景中存在-1 调整流。然而,FSDataInputStreamseek() 方法的文档明确指出,在寻找到一个位置之后,下一次读取将来自该位置,这意味着(?)上面的代码将是 1 个字节(?)。
那么,问题是,“-1”调整对于所有 InputSplit 阅读案例是否都是必要的?
顺便说一句,如果想要正确读取FileSplit,仅寻找它的开头是不够的,因为每个拆分也有一个结尾,可能与实际 HDFS 文件的结尾不同。因此,对应的InputStream 应该是“有界的”,即具有最大长度,如下所示:
InputStream is = new BoundedInputStream(fsin, split.getLength());
在这种情况下,在上面创建了“本机”fsin 蒸汽之后,使用 org.apache.commons.io.input.BoundedInputStream 类来实现“边界”。
更新
显然,只有LineRecordReader 类之一的用例行才需要进行调整,这超出了拆分的边界,以确保它读取完整的最后一行。
可以在earlier question 和MAPREDUCE-772 的cmets 中找到有关此问题的详细讨论。
【问题讨论】:
标签: java hadoop inputstream filesplitting input-split