如何设置"块大小"从Python subprocess.Popen()或open()读取文件的读取行?

时间:2016-09-15 11:28:34

标签: python bash shell subprocess chunking

我有一个相当大的文本文件,我想以块的形式运行。为了使用subprocess库执行此操作,可以执行以下shell命令:

"cat hugefile.log"

代码:

import subprocess
task = subprocess.Popen("cat hugefile.log", shell=True,  stdout=subprocess.PIPE)
data = task.stdout.read()

使用print(data)会立即吐出文件的全部内容。如何呈现块的数量,然后通过块大小访问该文件的内容(例如,chunk =一次三行)。

必须是这样的:

chunksize = 1000   # break up hugefile.log into 1000 chunks

for chunk in data:
    print(chunk)

Python open()的等效问题当然使用代码

with open('hugefile.log', 'r') as f:
     read_data = f.read()

你如何read_data大块?

1 个答案:

答案 0 :(得分:1)

使用文件,您可以迭代文件句柄(不需要子进程打开cat):

with open('hugefile.log', 'r') as f:
     for read_line in f:
        print(read_line)

Python通过读取最多\n的所有字符来读取一行。要模拟逐行I / O,只需调用它3次。或读取并计算3 \n个字符,但你必须处理文件的结尾等...不是很有用,你不会通过这样做获得任何速度。

with open('hugefile.log', 'r') as f:
     while True:
        read_3_lines = ""
        try:
           for i in range(3):
               read_3_lines += next(f)
        # process read_3_lines
        except StopIteration:  # end of file
            # process read_3_lines if nb lines not divisible by 3
            break

使用Popen你可以做同样的事情,作为奖励添加poll来监控流程(不需要使用cat但是我认为你的流程是不同的,那只是为了问题的目的)

import subprocess
task = subprocess.Popen("cat hugefile.log", shell=True,  stdout=subprocess.PIPE)
while True:
    line = task.stdout.readline()
    if line == '' and task.poll() != None: break

rc = task.wait()   # wait for completion and get return code of the command

支持Python 3兼容编码的代码:

    line = task.stdout.readline().decode("latin-1")
    if len(line) == 0 and task.poll() != None: break

现在,如果要将文件拆分为给定数量的块:

  • 出于显而易见的原因,您无法使用Popen:您必须先了解输出的大小
  • 如果您有一个文件作为输入,您可以执行以下操作:

代码:

import os,sys
filename = "hugefile.log"
filesize = os.path.getsize(filename)
nb_chunks = 1000
chunksize = filesize // nb_chunks

with open(filename,"r") as f:
   while True:
      chunk = f.read(chunksize)
      if chunk=="":
          break
      # do something useful with the chunk
      sys.stdout.write(chunk)