【问题标题】:hadoop filesystem open file and skip first linehadoop 文件系统打开文件并跳过第一行
【发布时间】:2020-01-22 05:31:11
【问题描述】:

我正在使用 Python 语言在我的 HDFS 中读取文件。

每个文件都有一个标题,我正在尝试合并这些文件。但是,每个文件中的标题也会被合并。

有没有办法跳过第二个文件的标题?

hadoop = sc._jvm.org.apache.hadoop
conf = hadoop.conf.Configuration()
fs = hadoop.fs.FileSystem.get(conf)

src_dir = "/mnt/test/"
out_stream = fs.create(hadoop.fs.Path(dst_file), overwrite)

files = []
for f in fs.listStatus(hadoop.fs.Path(src_dir)):
  if f.isFile():
    files.append(f.getPath())

for file in files:
  in_stream = fs.open(file)
  hadoop.io.IOUtils.copyBytes(in_stream, out_stream, conf, False)

目前我已经用下面的逻辑解决了这个问题,但是想知道是否有更好更有效的解决方案?感谢您的帮助

for idx,file in enumerate(files):
            if debug: 
                print("Appending file {} into {}".format(file, dst_file))

            # remove header from the second file
            if idx>0:
              file_str = ""
              with open('/'+str(file).replace(':',''),'r+') as f:
                for idx,line in enumerate(f):
                  if idx>0:
                    file_str = file_str + line

              with open('/'+str(file).replace(':',''), "w+") as f:
                f.write(file_str)
            in_stream = fs.open(file)   # InputStream object and copy the stream
            try:
                hadoop.io.IOUtils.copyBytes(in_stream, out_stream, conf, False)     # False means don't close out_stream
            finally:
                in_stream.close()

【问题讨论】:

    标签: python hadoop filesystems hdfs


    【解决方案1】:

    您现在正在做的是重复附加到一个字符串。这是一个相当缓慢的过程。为什么不在阅读时直接写入输出文件?

    for file_idx, file in enumerate(files):
      with open(...) as out_f, open(...) as in_f:
        for line_num, line in enumerate(in_f):
          if file_idx == 0 or line_num > 0:
            f_out.write(line)
    

    如果您可以一次加载所有文件,也可以使用readline 后跟readlines 跳过第一行:

    for file_idx, file in enumerate(files):
      with open(...) as out_f, open(...) as in_f:
        if file_idx != 0:
          f_in.readline()
        f_out.writelines(f_in.readlines())
    

    【讨论】:

    • 嗨,Adran,我了解解决方案,但是,我正在尝试覆盖现有文件,建议的解决方案是否适用于这种情况?
    • 如果您告诉open(..., 'w'),它将覆盖,请注意我们缺少+ 旁边的w 字符。如果您将+ 字符添加到第二个参数,它只会附加到文件中,例如w+。这不会删除文件,它只是完全替换了内容,所以如果你想要的话,请确保在将旧文件移动到 HDFS 之后删除带有 os.remove 之类的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    相关资源
    最近更新 更多