我想从某个偏移/位置读取大文件的子内容。例如,我有一个1 M行的文件,我想从第100行开始读取50行。(行号:101至150(含)
我想我应该使用PositionalReadable.https://issues.apache.org/jira/browse/HADOOP-519
我看到FSInputStream.readFully
实际上使用了Seekable
的seek()
方法。
当我检查seek()
的底层实现时,我看到它使用BlockReader.skip()
blockReader.skip()不会读取整个数据直到跳过字节的位置吗?问题是HDFS也会加载前100行以到达第101行吗?
如何在不加载其余内容的情况下使位置位于文件中的任何所需偏移量(如文件的第10000行)?一些s3在头偏移量中提供的功能。
下面是我发现的类似问题:How to read files with an offset from Hadoop using Java,但它建议使用seek()
,这是在评论中争论的seek()
是昂贵的操作,应该少用。我猜这是正确的,因为seek似乎读取所有的数据,以便跳到该位置。
1条答案
按热度按时间enyaitl31#
简短的回答可能会读取与
skip(n)
一样多的数据,也可能不会。正如您所说,seek()
内部调用BlockReader.skip()
。BlockReader
是一个接口类型,通过BlockReaderFactory()
创建。创建的BlockReader
实现为BlockReaderRemote
或BlockReaderLocal
。(确切地说,ExternalBlockReader
也是可能的,但由于它是一种特殊情况而被排除在外)当客户端通过RPC over TCP从网络上的远程DataNode读取数据时,将使用
BlockReaderRemote
。在这种情况下,如果分析skip()
方法代码,可以看到readNextPacket
被重复调用的次数与要跳过的n个字节一样多。也就是说,它实际读取要跳过的数据。BlockReaderLocal
在客户端与存储块的DataNode位于同一台计算机上时使用。在这种情况下,客户端可以直接读取块文件,并将dataPos
更改为在下一次读取操作时实际执行基于偏移量的跳过。