首页 > 解决方案 > 如何同时处理用于打印和存储到文件中的 UTF-8 字符串?

问题描述

我有一段代码从特定目录读取文件。然后它在控制台上打印文件名,并同时将它们写入日志文件。如果目录中的文件名中存在带有 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

我在编码/解码方面做错了。但是什么?

编辑

感谢下面@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:
  size = os.path.getsize(file)
except:
  size = 0

标签: pythonpython-3.xstringfileutf-8

解决方案


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')

推荐阅读