python - 如何同时处理用于打印和存储到文件中的 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
解决方案
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')
推荐阅读
- php - Symfony 路由 `options` 配置密钥
- extjs - ExtJS 网格 - 如果网格中的记录超过 10K,则取消选择“全选”复选框时会出现巨大延迟。如何减少这种延迟?
- javascript - gulp.dest 与 glob gulp.src - 使其相对
- python - 如何避免代码异味(else..if)语法?
- mysql - 为什么 PyMySQL 在使用 contextmanager 和 sqlalchemy 时这么早就关闭了?
- jenkins - 如何让 Jenkins Jobs 登录 Spinnaker UI
- jquery - 如何使用窗口打印功能打印条码标签?
- sql - 如何在mongodb中匹配相等的值
- r - 计算值 <0 的最小值?
- angular - 订阅父组件上的 ActionsSubject 不起作用