Сохранять стиль конца строки при работе с файлами в python

Я ищу способ гарантировать, что стиль конца файла поддерживается в программе python во время чтения, редактирования и записи.

У Python есть универсальная поддержка завершения файла, которая может преобразовать все окончания строки в \n при чтении файла, а затем преобразовать их все в системный по умолчанию при записи файла. В моем случае я хотел бы выполнить первоначальное преобразование, но затем напишу файл с исходным стилем EOL, а не по умолчанию.

Есть ли стандартный способ делать такие вещи? Если нет, существует ли стандартный способ определения стиля EOL для файла?

Предполагая, что нет стандартного способа сделать это, возможный рабочий поток:

  • Чтение в файле в двоичном режиме.
  • Декодирование в utf-8 (или требуемое кодирование).
  • Определите стиль EOL.
  • Преобразуйте все строки в \n.

  • Сделайте материал с файлом.

  • Преобразование всех строк в оригинальный стиль.

  • Кодировать файл.
  • Запись файла в двоичном режиме.

В этом потоке работы лучший способ сделать шаг 2?

Ответ 1

Использовать python универсальную поддержку новой строки:

f = open('randomthing.py', 'rU')
fdata = f.read()
newlines = f.newlines
print repr(newlines)

newlines содержит разделитель файла или кортеж разделителей, если файл использует комбинацию разделителей.

Ответ 2

Чтобы сохранить исходные окончания строк, используйте newline='' для чтения или записи непереведенных окончаний строк.

with open('test.txt','r',newline='') as rf:
    content = rf.read()
content = content.replace('old text','new text')
with open('testnew.txt','w',newline='') as wf:
    wf.write(content)

Обратите внимание, что если сама текстовая манипуляция имеет дело с окончаниями строк, может потребоваться дополнительная или альтернативная логика для обнаружения и сопоставления исходных концов строк.

Режим 'U' также работает, но не рекомендуется.

Документация Python: открытая

newline контролирует, как работает универсальный режим новой строки (это относится только к текстовому режиму). Это может быть None, '', '\n', '\r' и '\r\n'. Это работает следующим образом:

• При чтении ввода из потока, если для новой строки установлено значение "Нет", включается режим универсальной новой строки. Строки на входе могут оканчиваться на '\n', '\r' или '\r\n', и они переводятся в '\n' перед возвратом вызывающей стороне. Если это '', включается универсальный режим перевода строки, но окончания строки возвращаются вызывающей стороне без перевода. Если он имеет какие-либо другие допустимые значения, входные строки заканчиваются только данной строкой, а окончание строки возвращается вызывающей стороне без перевода.

• При записи вывода в поток, если символ новой строки равен None, любые написанные символы '\n' транслируются в системный разделитель строк по умолчанию, os.linesep. Если символ новой строки '' или '\n', перевод не выполняется. Если символ новой строки является любым из других допустимых значений, любые написанные символы '\n' преобразуются в данную строку.