我的python写入文件正常,打开后却是乱码格式为什么?
windows7 +2.7.5
我的源代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
file = open(r"D:\Android\python\test.txt","w+")
file.write('hello')
file.read()
python test1.py后,用记事本打开文件显示乱码,请问这是怎么回事啊?
Windows下的编码是个大坑,别用记事本了,换nodepad++吧。
请特别阅读 @依云 的答案。分析上游代码和文档,这才是真正坚不可摧的力量。
同仁们,误入歧途了啊!!!别在ASCII的文件上这么深入的追究编码问题啊!!!
我试了一下,果然爽翻:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
f = open(r"C:\Users\776\test.txt","w+")
# 注:w+ truncates the file - 因此文件无论存在与否,结果一致
f.write('hello')
print(f.read())
f.close()
# 结果不贴了,同样不忍直视,传送门:http://paste.openstack.org/show/61806/
我没有深入的究其原因,不过大概能猜到理由是什么:文件的指针位置。
open()
以w+模式开启了一个读写模式的文件,由于是w,所以文件被废弃清空(truncate),此时的文件内容为[EOF]
,开启时的指针为0。此时如果做read()
,则Python发现指针位置就是EOF,读取到空字符串。
在写入hello之后,指针的位置是5,文件在内存中是hello[EOF]
。
但看起来read()的时候,Python仍然去试图在磁盘的文件上,将指针从文件头向后跳5,再去读取到EOF为止。
也就是说,你实际上是跳过了该文件真正的EOF,为硬盘底层的数据做了一个dump,一直dump到了一个从前文件的[EOF]
为止。所以最后得到了一些根本不期待的随机乱字符(这里根本不是编码问题造成的乱码!)。
(看起来似乎还暴露了一些以前文件的内容呢,C:\Anaconda\
神马的 :D)
解决这个问题,你需要在读文件之前,用file对象的flush()
方法,将已修改的文件内容可靠写盘:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
f = open(r"C:\Users\776\test.txt","w+")
# 注:w+ truncates the file - 因此文件无论存在与否,结果一致
f.write('hello') # 此时指针=5,内存内容=`hello[EOF]`
f.flush() # 此时硬盘内容=`hello[EOF]`
print(f.read()) # 此时指针=5,正好在[EOF]上,正确输出''
f.seek(0) # 指针归0
print(f.read()) # 正确从头读出全部内容'hello'
f.close()
这并不是完美的解决方法,因为我总觉得flush()
应该是真正决定写盘之前才做的,而不是read()
一次就flush()
一次。read()
似乎还是优先读取内存缓冲区更有道理。
但总之至少猜测到了一个原因,并一定程度解决问题,更好的方法有待补充吧?
乱码应该是报错信息,读文件之前先打开,最后还最好要 close
试试下面这个
#!/usr/bin/env python
# -*- coding: utf-8 -*-
file = open(r"D:\Android\python\test.txt","w+")
file.write('hello')
file = open("D:\Android\python\test.txt")
file.read()
file文件的读写,一定要注意,在写完之后,必须要seek(0),把文件指针重新指向文件开头,然后再读,否则就会从缓冲区读取一大堆乱码——顺便,这是不是一个潜在的缓冲区溢出漏洞啊。
更新:
我在路上就在想,这么底层的一个特性,为什么 Python 没有为程序员处理掉呢?都用 Python 了,谁会为了那么大的便利牺牲一丁点性能呢?一回来我就做了测试。
经测试,Python 2.7.5 on Windows XP 重现此情况,Python 3.3.2 on Windows XP 没有重现。这说明 Python 2 确实该换了!
再次更新:
找到原因之后我就觉得这问题在哪里见过,今天终于找出来了, python-cn 邮件列表里讨论过的。
真正的答案来啦~~我在 MSDN 里找得好苦哦 QAQ
真正的原因不在于 Python 怎么样了,而在于 Windows 怎么样了。经查源码(Python 2.7.6)Objects/fileobject.c:2837
,Python 是使用 fopen/fread/fwrite
这系列函数来读写文件的。MSDN 说:
所以会有 @沙渺 发现添加 flush()
调用后正确的结果。
Linux 下没有重现。man 3 fopen
说:
所以 Windows 的这种行为是符合 ANSI C 标准的,但是 Linux 并不(总是)需要这样做。(并且,跨平台的方案是使用文件定位函数而不是 fflush()
。)
玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/wenda/wd19887.html
相关文章 Recommend
- • 2019年3月最新消息: Python 3.4.10 现已推出
- • [上海]招Python量化系统开发工程师
- • 优集品网络科技有限公司招Python中/高级工程师
- • 爱因互动科技发展有限公司招募Python开发攻城狮
- • mozio招聘Python/Django工程师
- • Kavout金融科技公司招Python研发工程师
- • Python数组逆向输出,编程练习题实例四十
- • Python数组插入排序,编程练习题实例三十九
- • Python矩阵for循环应用,编程练习题实例三十八
- • Python操作Redis数据库方面的问题
- • 请python高手帮我看看这段python代码中函数setter的
- • Python什么方法可以快速将两个队列变成字典
必知PYTHON教程 Must Know PYTHON Tutorials
- • python 解释器
- • python idle
- • python dir函数
- • python 数据类型
- • python type函数
- • python 字符串
- • python 整型数字
- • python 列表
- • python 元组
- • python 字典
- • python 集合
- • python 变量
- • python print
- • python 函数
- • python 类定义
- • python import
- • python help
- • python open
- • python 异常处理
- • python 注释
- • python continue
- • python pass
- • python return
- • python global
- • python assert
- • python if语句
- • python break
- • python for循环
- • python while循环
- • python else/elif
- • lambda匿名函数
必知PYTHON模块 Must Know PYTHON Modules
- • os 模块
- • sys 模块
- • re 正则表达式
- • time 日期时间
- • pickle 持久化
- • random 随机
- • csv 模块
- • logging 日志
- • socket网络通信
- • json模块
- • urlparse 解析URL
- • urllib 模块
- • urllib2 模块
- • robotparser 解析
- • Cookie 模块
- • smtplib 邮件
- • Base64 编码
- • xmlrpclib客户端
- • string 文本
- • Queue 线程安全
- • math数学计算
- • linecache缓存
- • threading多线程
- • sqlite3数据库
- • gzip压缩解压
最新内容 NEWS
- • django app提供pv信息的方法是什么
- • Django项目版本升级如何操作?
- • django较多数据传递如何优雅的呈现
- • django1.7获取参数问题求助
- • Django1.7使用内置comment遇到问题
- • python mysql数据库做insert操作时报_mysql_ex
- • 关于python mysql的duplicate insert机制的疑问
- • pymongo使用insert函数批量插入被中断要怎么
- • Python程序员解决棘手问题的常用库
- • 求助关于restfull api接口几个问题
图文精华 RECOMMEND
-
django1.7获取参数问题求助
-
Python程序员解决棘手问题的常用库
-
求问str()同__str__原理上有什么不同
-
scrapy框架里面用link extractor怎么能
-
python {}.fromkeys创建字典append添加操
-
python3 类型Type str doesn't support th
热点文章 HOT
- 学习Python有什么好的书籍推荐?
- Python匿名函数 Lambda表达式作用
- Python与Java、C、Ruby、PHP等编程语言有什么
- Python 正则中文网页字符串提取问题
- 如何为实时性应用存取经纬度?django my
- 想用python做个客户端,在二维码登录这个地
- 有让IDE可识别Python函数参数类型的方法吗
- Python字符串转换成列表正则疑问