2015-04-17 3 views
0

я хочу заменить Юникод символ в файл с питономпитон юникода заменить MemoryError

это мой код:

with codecs.open('/etc/bluetooth/main.conf', "r", "utf8") as fi: 
      mainconf=fi.read() 
     forrep = ''.decode('utf8') 
     for line in mainconf.splitlines(): 
      if('Name = ' in line): 
       forrep = line.split('=')[1] 
     print 'name',type(name) 
     print 'mainconf',type(mainconf) 
     print 'forrep',type(forrep) 
     mainconf = mainconf.replace(forrep, name) 
     #mainconf = mainconf.replace(forrep.decode('utf8'),' '+name) 
     with codecs.open('/etc/bluetooth/main.conf','w',"utf8") as fi: 
      fi.write(mainconf) 

но питон всегда получает меня ошибку MemoryError ...

это:

name <type 'unicode'> 
mainconf <type 'unicode'> 
forrep <type 'unicode'> 
Traceback (most recent call last): 
    File "WORK/Bluetooth/Bluetooth.py", line 359, in <module> 
    if __name__ == '__main__':main() 
    File "WORK/Bluetooth/Bluetooth.py", line 336, in main 
    BLMan.SetAllHCIName(common.cfg.get('BLUETOOTH', 'HCI_DEVICE_NAME')) 
    File "WORK/Bluetooth/Bluetooth.py", line 194, in SetAllHCIName 
    mainconf = mainconf.replace(forrep, name) 
MemoryError 
+0

открыть файл для чтения и записи режим в первой строке и записать это. – Janom

+0

Насколько велик 'main.conf'? На какой платформе вы работаете? – abarnert

+0

В качестве примечания: Что такое 'forrep = '.decode (' utf8 ')' for? Все, что вам нужно сделать, это создать пустую строку unicode 'u''', которая (а) вы могли бы просто написать как литерал, и (б) вы нигде не используете. Я немного обеспокоен тем, что вы ожидаете, что «декодирование» каким-то образом запомнится и автоматически будет повторно применено в любое время, когда вы сохраните что-нибудь под именем 'forrep' позже или что-то, чего не будет. – abarnert

ответ

1

Итерации над файловым объектом, вы храните весь файл Содержание ля в памяти с помощью mainconf=fi.read():

with codecs.open('/etc/bluetooth/main.conf', "r", "utf8") as fi: 
    for line in fi: 

Вы хранить все строки с чтением затем хранить список всех линий с использованием splitlines, так что вы сохраняете все содержимое файла в два раз и, как @abarnet отметил в комментарии затем попытайтесь сохранить третью копию с помощью mainconf = mainconf.replace(forrep, name).

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

Я понятия не имею, что имя, но писать на TempFile будет самым эффективным способом сделать то, что вы хотите:

from tempfile import NamedTemporaryFile 

with open('/etc/bluetooth/main.conf') as fi, NamedTemporaryFile(dir=".", delete=False) as out: 
    for line in fi: 
     if line.startswith("Name ="): 
      a, b = line.split("=",1) 
      out.write("{} = {}".format(a, name.encode("utf-8"))) 
     else: 
      out.write(line) 

move(out.name, '/etc/bluetooth/main.conf') 
+1

Это правильная идея, но обратите внимание, что он хочет переписать файл в конце. Поэтому ему нужно немного больше. Возможно открытие временного файла, запись строки за строкой при чтении строки за строкой, а затем перемещение временного файла поверх оригинала. – abarnert

+0

@abarnert, True a NamedTempFile должен работать или, возможно, использовать fileinput.input. OP фактически хранит содержимое дважды, что не помогает ни –

+0

Yea, 'NamedTempfile' идеально, за исключением того, что это немного больно, чтобы обернуть его в модуль' codecs'. (Если это Python 2.6+, он может использовать 'io' вместо' codecs', хотя ...) – abarnert

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