Лучший подход для чтения/записи файлов в python?

Предположим, у меня есть файл (скажем, file1.txt) с данными около 3 МБ или больше. Если я хочу записать эти данные во второй файл (скажем, file2.txt), какой из следующих подходов будет лучше?

Используемый язык: Python 2.7.3.

Подход 1:

file1_handler = file("file1.txt", 'r')
for lines in file1_handler:
    line = lines.strip()
    # Perform some operation
    file2_handler = file("file2.txt", 'a')
    file2_handler.write(line)
    file2_handler.write('\r\n')
    file2_handler.close()
file1_handler.close()

Подход 2:

file1_handler = file("file1.txt", 'r')
file2_handler = file("file2.txt", 'a')
for lines in file1_handler:
    line = lines.strip()
    # Perform some operation
    file2_handler.write(line)
    file2_handler.write('\r\n')
file2_handler.close()
file1_handler.close()

Я думаю, что подход два будет лучше, потому что вам просто нужно открыть и закрыть file2.txt один раз. Что ты говоришь?


person Hemant    schedule 20.03.2013    source источник
comment
Откройте файл с open, а не с файл.   -  person Matthias    schedule 20.03.2013


Ответы (3)


Используйте with, он автоматически закроет файлы для вас:

with open("file1.txt", 'r') as in_file, open("file2.txt", 'a') as out_file:
    for lines in in_file:
        line = lines.strip()
        # Perform some operation
        out_file.write(line)
        out_file.write('\r\n')

Используйте open вместо file, file устарело.

Конечно, неразумно открывать файл2 на каждой строке файла1.

person Pavel Anossov    schedule 20.03.2013
comment
Я писал то же самое :) @Hemant, посмотри: docs.python.org/2/whatsnew/2.5.html#pep-343-the-with-statement - person Francesco Frassinelli; 20.03.2013
comment
Что касается f2.write('\r\n'): для этого вам нужно открыть f2 как двоичный файл (добавив b к флагу). - person Francesco Frassinelli; 20.03.2013
comment
ой! Я думал, что open устарел: p (я не читал документы должным образом), так что скорость записи увеличивается? Потому что первый подход занимал почти 2 часа на копирование 1 МБ данных. - person Hemant; 20.03.2013
comment
@Francesco: не могли бы вы немного объяснить этот подход к двоичному файлу? - person Hemant; 20.03.2013
comment
@Hemant: посмотри: посмотри: stackoverflow.com/questions/2536545/ Если вы пишете \n без двоичного режима, Python будет использовать более подходящую конечную строку для вашей платформы. Если вы хотите использовать определенную конечную строку, вы должны использовать двоичный флаг. - person Francesco Frassinelli; 20.03.2013
comment
Это актуально только для окон. Python для Windows различает текстовые и двоичные файлы; символы конца строки в текстовых файлах автоматически слегка изменяются при чтении или записи данных. - person Pavel Anossov; 20.03.2013
comment
@Hemant: вы могли бы подумать о реализации буфера, чтобы сделать пару больших записей, а не много маленьких. Вы можете просто добавить свои строки в список и, когда список станет достаточно большим, написать их все. - person Francesco Frassinelli; 20.03.2013
comment
@Francesco: причина использования '\r\n' в том, что я хочу ввести следующую строку из файла1 в следующую строку файла2. делает ли это двоичный режим или просто сохраняет «\ r \ n» как есть? - person Hemant; 20.03.2013
comment
@Хемант: да. \r\n для Windows, на Linux/Mac у вас есть \n. Если вы работаете в Linux и хотите писать как Windows (например), вам нужно использовать двоичный режим и писать \r\n. - person Francesco Frassinelli; 20.03.2013
comment
@Francesco: я попытаюсь реализовать этот буферный подход :) - person Hemant; 20.03.2013
comment
Двоичный режим не влияет на Unix. Он пишет то, что ему говорят писать. - person Pavel Anossov; 20.03.2013
comment
@Francesco: я тебя не понимаю... твоё "да" для какого ответа? преобразование в новую строку или запись '\r\n' как есть? - person Hemant; 20.03.2013
comment
Текстовый режим в Windows преобразует \r и \n в \r\n. \r\n остается без изменений. - person Pavel Anossov; 20.03.2013
comment
@PavelAnossov спасибо за информацию. Hemant: Павел Аносов ответил правильно :) - person Francesco Frassinelli; 20.03.2013

Я недавно делал что-то подобное (если я вас правильно понял). Как насчет:

file = open('file1.txt', 'r')
file2 = open('file2.txt', 'wt')

for line in file:
  newLine = line.strip()

  # You can do your operation here on newLine

  file2.write(newLine)
  file2.write('\r\n')

file.close()
file2.close()

Этот подход работает как шарм!

person Oscar_Mariani    schedule 20.03.2013

Мое решение (получено от Павла Аносова + буферизация):

dim = 1000
buffer = []
with open("file1.txt", 'r') as in_file, open("file2.txt", 'a') as out_file:
    for i, lines in enumerate(in_file):
        line = lines.strip()
        # Perform some operation
        buffer.append(line)
        if i%dim == dim-1:
            for bline in buffer:
                out_file.write(bline)
                out_file.write('\r\n')
            buffer = []

Павел Аносов первым дал правильное решение: это всего лишь предложение ;) Вероятно, существует более элегантный способ реализации этой функции. Если кто-то знает, пожалуйста, сообщите нам.

person Francesco Frassinelli    schedule 20.03.2013
comment
@ Francesco: Эй, спасибо за этот ответ :) но я не очень хорошо знаком с методом enumerate. Можете, пожалуйста, объяснить мне преимущества использования enumerate? - person Hemant; 21.03.2013
comment
@Hemant: enumerate полезен :) Посмотрите здесь: docs.python.org/2 /library/functions.html#enumerate - person Francesco Frassinelli; 21.03.2013
comment
@ Франческо: спасибо за документ. теперь я понимаю ваш пример более четко. :) - person Hemant; 21.03.2013