2016-09-15 2 views
0

У меня довольно большой текстовый файл, который я бы хотел запустить в кусках. Для того, чтобы сделать это с помощью subprocess библиотеки, можно было бы выполнить следующую команду оболочки:Как установить размер «chunk» для чтения строк из файла, прочитанного с помощью подпроцесса Python.Popen() или open()?

"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

Использование файла, вы можете перебирать на дескриптор файла (нет необходимости подпроцесса, чтобы открыть cat):

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

Python читает строку, прочитав все символы до \n. Чтобы имитировать линейный ввод-вывод, просто вызовите его 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) 
+0

Спасибо за это. Что такое априори, я не знал о трех строках, но я просто хотел, чтобы файл разбился на '10 ** 7' кусков? – ShanZhengYang

+0

Вы имеете в виду куски 10 ** 7 байт? и вам нужен Попен или нет? это ваш реальный случай с использованием 'cat', или это просто для простоты вопроса? –

+0

Я имею в виду разделить файл на 10 ** 7 разделов, не беспокоясь о размере байта. В приведенном выше примере 'nb_chunks' составляет 1000 байтов --- что, если мы разбираем строки размером 750 байтов каждый, можно ли отрезать некоторые строки? Мне нужен Popen(), да.Кошка - простой пример – ShanZhengYang

Смежные вопросы