Как обработать строку UTF-8 для печати и сохранения в файл одновременно? - PullRequest
0 голосов
/ 05 января 2019

У меня есть кусок кода, который читает файлы из определенного каталога. Затем он печатает имена файлов на консоли и - одновременно - записывает их в файл журнала. Если в имени файла в каталоге есть файл с символом Unicode, сценарий останавливается с ошибкой. Я разобрался, как напечатать имя файла. Но я не понял, как записать имя файла в файл журнала.

Это мой код (на Mac файловая система UTF-8):

import sys
import os

rootdir = '/Volumes/USB/dir/'
logfile = open('temp.txt', 'a')

for subdir, dirs, files in os.walk(rootdir):
    for file in files:                                                  
        file = os.path.join(subdir, file)  
        file2 = file.encode('utf-8')
        print(file2)
        logfile.write('Reading file: "'+file+'"\n')

В этом случае ошибка

b'/Volumes/USB/dir/testa\xcc\x88test.mp4'
Traceback (most recent call last):
  File "/temp/list-files-in-dir.py", line 15, in <module>
    logfile.write('Reading file: "'+file+'"\n')
UnicodeEncodeError: 'ascii' codec can't encode character '\u0308' in position 46: ordinal not in range(128)

Когда я изменяю последнюю строку на

    logfile.write('Reading file: "'+file2+'"\n')

тогда ошибка

Traceback (most recent call last):
  File "/temp/list-files-in-dir.py", line 15, in <module>
    logfile.write('Reading file: "'+file2+'"\n')
TypeError: must be str, not bytes

Я делаю что-то не так с кодировкой / декодированием. Но что?

EDIT

Благодаря комментарию @lenz внизу я теперь могу писать в лог-файл.

Затем я добавил новую строку в код

size = os.path.getsize(file)

и теперь я получаю новую ошибку:

Traceback (most recent call last):
  File "/temp/list-files-in-dir.py", line 16, in <module>
    size = os.path.getsize(file)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
FileNotFoundError: [Errno 2] No such file or directory: '/Volumes/USB/dir/testa\xcc\x88test.mp4'

Кажется, что эта внутренняя функция также имеет некоторые проблемы с UTF-8. Я снова застрял.

РЕДАКТИРОВАТЬ 2

Нет решения, но я нашел обходной путь для размера файла, добавив условие try.

try:
  size = os.path.getsize(file)
except:
  size = 0

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Я обнаружил, что эта проблема возникает только при запуске сценария из редактора кода Visual Studio с расширением MagicPython. Когда я запускаю этот код из обычной оболочки, все работает, как ожидалось, и обработка UTF-8 выполняется правильно.

0 голосов
/ 05 января 2019

Строки Python 3 являются Unicode по умолчанию. Откройте файл с нужной вам кодировкой и не кодируйте вручную. Это исправит вашу более позднюю проблему с os.path.getsize, так как она также хочет строку Unicode.

import os

rootdir = '/Volumes/USB/dir/'

# "with" will close the file when its block is exited.
# Specify the encoding when opening the file.
with open('temp.txt','w',encoding='utf8') as logfile:
    for subdir, dirs, files in os.walk(rootdir):
        for file in files:                                                  
            file = os.path.join(subdir, file)  
            print(file)
            logfile.write('Reading file: "'+file+'"\n')
...