Python从HDFS读取文件作为流

Cha*_*guy 25 python hadoop subprocess hdfs

这是我的问题:我在HDFS中有一个文件可能很大(=不足以满足所有内存)

我想要做的是避免将此文件缓存在内存中,并且只像我对常规文件那样逐行处理:

for line in open("myfile", "r"):
    # do some processing
Run Code Online (Sandbox Code Playgroud)

我希望看看是否有一种简单的方法可以在不使用外部库的情况下完成这项工作.我大概可以使其与工作libpyhdfs蟒蛇,HDFS,但我想如果可能的话,以避免在系统中引入新的依赖和未经考验的库,特别是因为这两个似乎没有大量维护和状态,他们不应该用于生产.

我想做到这一点使用标准的"Hadoop的"命令行工具,使用Python subprocess模块,但我似乎无法能够做什么,我需要的,因为没有命令行工具,会做我处理,我想以流方式为每一行执行Python函数.

有没有办法使用子进程模块将Python函数应用为管道的正确操作数?或者甚至更好,打开它就像一个文件作为生成器,所以我可以轻松处理每一行?

cat = subprocess.Popen(["hadoop", "fs", "-cat", "/path/to/myfile"], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

如果有另一种方法可以在不使用外部库的情况下实现上述描述,我也非常开放.

谢谢你的帮助 !

Kei*_*all 39

你想要xreadlines,它从文件中读取行而不将整个文件加载到内存中.

编辑:

现在我看到你的问题,你只需要从你的Popen对象获取stdout管道:

cat = subprocess.Popen(["hadoop", "fs", "-cat", "/path/to/myfile"], stdout=subprocess.PIPE)
for line in cat.stdout:
    print line
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果将-cat替换为-text,它也将处理压缩. (3认同)
  • 请注意,自2.3以来,[`xreadlines`已被弃用](http://docs.python.org/release/2.3/lib/module-xreadlines.html)(只需使用`for line in file`,就像你的*一样*编辑**). (3认同)

sim*_*leo 29

如果你想不惜任何代价避免添加外部依赖,Keith的答案是要走的路. 另一方面,Pydoop可以让您的生活更轻松:

import pydoop.hdfs as hdfs
with hdfs.open('/user/myuser/filename') as f:
    for line in f:
        do_something(line)
Run Code Online (Sandbox Code Playgroud)

关于您的担忧,Pydoop积极开发并已在CRS4中用于生产多年,主要用于计算生物学应用.

西蒙娜

  • [hdfscli](http://hdfscli.readthedocs.org/en/latest/)具有类似的功能,而且更轻巧.不要忘记启用WebHDFS来使用它. (2认同)