2015-06-22 4 views
4

У меня есть .Mesh-файл размером ~ 600 МБ Roblox, который читается как текстовый файл в любом текстовом редакторе. У меня есть следующий код ниже:Python - открытие и изменение больших текстовых файлов

mesh = open("file.mesh", "r").read() 
mesh = mesh.replace("[", "{").replace("]", "}").replace("}{", "},{") 
mesh = "{"+mesh+"}" 
f = open("p2t.txt", "w") 
f.write(mesh) 

Она возвращает:

Traceback (most recent call last): 
    File "C:\TheDirectoryToMyFile\p2t2.py", line 2, in <module> 
    mesh = mesh.replace("[", "{").replace("]", "}").replace("}{", "},{") 
MemoryError 

Вот пример моего файла:

[-0.00599, 0.001466, 0.006][0.16903, 0.84515, 0.50709][0.00000, 0.00000, 0][-0.00598, 0.001472, 0.00599][0.09943, 0.79220, 0.60211][0.00000, 0.00000, 0] 

Что я могу сделать?

Edit:

Я не уверен, что голова, следовать, и команда хвоста в этом другом потоке, который отмечается в этом как дубликат. Я попытался использовать его, но не смог заставить его работать. Файл также является одной гигантской линией, он не разбивается на строки.

+0

попытаться сделать то заменить один на один раз. Попробуйте прочитать некоторые уроки. – wwii

+1

Это не сработало – GShocked

+0

Возможный дубликат [Прочитать большие текстовые файлы в Python, строка за строкой, не загружая его в память] (http://stackoverflow.com/questions/6475328/read-large-text-files-in -python-line-by-line-without-load-it-in-to-memory) –

ответ

4

Вы должны прочитать один укус каждой итерации, анализировать ее, а затем записать в другой файл или sys.stdout. Попробуйте этот код:

mesh = open("file.mesh", "r") 
mesh_out = open("file-1.mesh", "w") 

c = mesh.read(1) 

if c: 
    mesh_out.write("{") 
else: 
    exit(0) 
while True: 
    c = mesh.read(1) 
    if c == "": 
     break 

    if c == "[": 
     mesh_out.write(",{") 
    elif c == "]": 
     mesh_out.write("}") 
    else: 
     mesh_out.write© 

UPD:

Он работает очень медленно (благодаря jamylak). Поэтому я изменил его:

import sys 
import re 


def process_char(c, stream, is_first=False): 
    if c == '': 
     return False 
    if c == '[': 
     stream.write('{' if is_first else ',{') 
     return True 
    if c == ']': 
     stream.write('}') 
     return True 


def process_file(fname): 
    with open(fname, "r") as mesh: 
     c = mesh.read(1) 
     if c == '': 
      return 
     sys.stdout.write('{') 

     while True: 
      c = mesh.read(8192) 
      if c == '': 
       return 

      c = re.sub(r'\[', ',{', c) 
      c = re.sub(r'\]', '}', c) 
      sys.stdout.write(c) 


if __name__ == '__main__': 
    process_file(sys.argv[1]) 

Так что теперь он работает ~ 15 секунд в файле 1.4G. Для того, чтобы запустить его:

$ python mesh.py file.mesh > file-1.mesh 
+0

приятно. см. также этот вопрос http://stackoverflow.com/questions/2872381/how-to-read-a-file-byte-by-byte-in-python-and-how-to-print-a-bytelist-as- a-binar – maxymoo

+0

Может быть хорошей идеей работать * внутри * менеджера контекста, используя инструкцию '' 'with'''. '' 'mesh_out''' следует открыть для * добавления * – wwii

+1

Чтение' 1' байт за один раз очень медленное. Вы должны использовать размер буфера, например. default '8192' и запустите' .replace() 'на каждом куске – jamylak

1

Вы могли бы сделать его построчно:

mesh = open("file.mesh", "r") 
with open("p2t.txt", "w") as f: 
    for line in mesh: 
     line= line.replace("[", "{").replace("]", "}").replace("}{", "},{") 
     line = "{"+line +"}" 
     f.write(line) 
+0

По-прежнему ошибка памяти, может быть, мне нужно больше баранов? У меня 8 ГБ, но одна из моих палочек не удалась, и у меня только 4 ГБ теперь – GShocked

+0

попробуйте сейчас, это должно итерации по линиям – maxymoo

+0

По-прежнему получена ошибка памяти – GShocked

0
import os 
f = open('p2f.txt','w') 
with open("file.mesh") as mesh: 
    while True: 
    c = mesh.read(1) 
    if not c: 
     f.seek(-1,os.SEEK_END) 
     f.truncate() 
     break 
    elif c == '[': 
     f.write('{') 
    elif c == ']': 
     f.write('},') 
    else: 
     f.write(c) 

p2f.txt:

{-0.00599, 0.001466, 0.006},{0.16903, 0.84515, 0.50709},{0.00000, 0.00000, 0},{-0.00598, 0.001472, 0.00599},{0.09943, 0.79220, 0.60211},{0.00000, 0.00000, 0} 
+0

Чтение на' 1 'byte в то время очень медленный, как я уже говорил. Вы должны прочитать размер большего буфера. Если вы не верите, что я смотрю, что сказал об этом Линус Торвальдс – jamylak

+0

@jamylak Я согласен, но я пытался избежать MemoryError :) –

+0

Нет, это не так, память способна хранить более 1 байт за раз , – jamylak

-1
def read(afilename): 
    with open("afilename", "r") as file 
     lines = file.readlines() 
     lines.replace("[", "{") 
     #place reset of code here in 
+2

'lines = file.readlines()' уже убивает память – jamylak

+0

, которая будет зависеть от размера файла, который читается/записывается ??. в небольшом файле, не могли бы вы сказать, что заметили бы это? – AuzPython

+0

В небольшом файле вы не заметите. но вопрос в частности заключается в «открытии больших файлов» и говорит «файл 600mb». Также его плохая практика использовать '.readlines()', я никогда не использую ее – jamylak

1
BLOCK_SIZE = 1 << 15 
with open(input_file, 'rb') as fin, open(output_file, 'wb') as fout: 
    for block in iter(lambda: fin.read(BLOCK_SIZE), b''): 
     # do your replace 
     fout.write(block) 
Смежные вопросы