python 用 while 读文件怎么检测文件结束 ?

2014-11-13 10:10:54 +08:00
 yakczh
filename=r'err.txt'

lineno=0
for line in open(filename,mode='r',encoding='utf8'):
lineno+=1
try:
print(lineno)
#print (lineno,line[0])
pass
except:
print ('ERROR'),lineno


err.txt 文件内容
#AND ( ( `goods_name` LIKE '%环球•海港城%' ) OR ( `buildName` = '环球•海港城' )

因为文件中有特殊字符,用for line in open(file) 这样 即使捕获异常也会中止
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 6629-6630: invalid continuation byte


如果用while方式

file= open(filename,mode='r',encoding='utf8')
line=''
lineno=1
while 1:
try:
line = file.readline()
print(lineno),
except:
line='\tERROR'
print(line)
if not line:
break
else:
print("next")
lineno+=1

这样如果读到空行,就直接退出了,用While怎么样检测读到文件尾?
8981 次点击
所在节点    问与答
14 条回复
Sylv
2014-11-13 10:41:45 +08:00
首先你要解决那个编码错误,要不然怎么写都是会出错的。看样子像是这个文件并不是 utf8 编码的,你用 utf8 去读它就出问题了,检查下文件编码,然后使用对应的编码来 open。

另外如果你用这种方式打开文件的话,要记得最后要 file.close。
更好的方式是这样:
with open('somefile') as openfileobject:
-- for line in openfileobject:
-- -- do_something()
yakczh
2014-11-13 12:50:58 +08:00
@Sylv

这个文件是utf8编码的, 只是其中有些特殊字符而已 ,比如1000行,其中500行有一个特殊字符程序就会退出,这个文件是一个sql日志文件,是mysql生成的, 我的思路是如果读到特殊字符就当作一个异常处理 pass ,不影响到后续的数据,而不是象现在这样中途退出

-- for line in open(filename,mode='r',encoding='utf8'):
-- -- try:
-- -- -- -- do_something()

这样根本捕获不了异常 貌似读每行的操作在是 for line in open(filename,mode='r',encoding='utf8'):这条语句里,我想用
while True:
-- --try:
-- -- -- -- line=file.readline()

这样把读操作写到try里面
但这样需要一个判断文件结束的标志,才能Break出来
yakczh
2014-11-13 12:55:24 +08:00
附文件内容
err.txt
1
2
3
4
5
6
7
9
9

AND ( ( `goods_name` LIKE '%环球•海港城%' ) OR ( `buildName` = '环球•海港城' )

11
12
13
14
15
Jaylee
2014-11-13 12:59:11 +08:00
mode="rb"
yakczh
2014-11-13 13:13:52 +08:00
@Jaylee

fp= open(filename,mode='rb')
while True:
-- try:
-- line = fp.readline()
-- except:
-- -- print('erro')
-- -- pass
-- if not line: # if not line: 这样写 line有可能出现异常
-- -- break
有办法不用line 来判断读到文件尾吗?
Sylv
2014-11-13 16:06:24 +08:00
@yakczh 什么特殊字符?我感到困惑的是,如果这些特殊字符也是用utf8正确编码的,那为什么用utf8去读取会出错?
可以把这个文件传网盘之类的,贴上看看吗?

关于 readine(),你去看文档就会知道如果返回空字符串就说明到文件尾了,所以用 if not line 来判断是可以的。你说这样会出异常,出的是什么异常?
clino
2014-11-13 16:29:14 +08:00
没错,我首先想到的就是楼上sylv的这种方法,判断是否空串就行了,这种方法不一定要readline吧,read也行
staticor
2014-11-13 16:44:45 +08:00
好像这样操作可以正常读完呀..

```
with open(filename, mode='rb') as f
for line in f:
try:
print(line.decode('utf-8'), end="")
except Exception:
print("Encoding Error")
```
lcqtdwj
2014-11-13 16:56:06 +08:00
我觉得你问题解决层面不对,应该在数据来源解决。
yakczh
2014-11-13 17:01:07 +08:00
@Sylv

这个文件是mysql生成的

SET timestamp=1415753930;
UPDATE cdb_forum_thread SET subject='Ϸ˄ЕƱ˛��ųƱ' WHERE closed='397758';

SET timestamp=1415753936;
select did,buildname,mapcode_x,mapcode_y,address,areaid,comareaid,buildtype from hellohouse_dictionary where buildname like '%軧둂ͬء86-200%u33a1%u51c6%u73b0%u623f%u5b9e%u666f%u5448%u73b0%uff0c%u5168%u57ce%';
# Time: 141112 8:58:59


如果用户浏览器刷新的时候页面编码不对,这时候又点提交表单,这些乱码就会提交到mysql ,然后mysql会原样记录在Sql里面
Sylv
2014-11-13 17:17:33 +08:00
@yakczh 你贴文件内容上来没用啊,得传整个文件上来才好知道是哪里编码出问题了。
我赞同 lcqtdwj 说的,应该从数据源来解决问题。我理解是这个文件中有部分字符不是用utf8编码的,所以读取出错。可以试着把源文件全部内容转换为utf8编码后再读取。

如果按你的想法,应该 staticor 的方法是正解。
lcqtdwj
2014-11-13 21:41:29 +08:00
@yakczh 在表单存入数据库之前应该检查request的charset,根据charset编码转换为适当的编码再存入数据库
yakczh
2014-11-14 09:43:03 +08:00
@staticor

filename=r'mysql_slow.log'
mass=''
with open(filename, mode='rb') as f:
--for line in f:
----valid=True
----try:
------sql=line.decode('utf-8')
------print(sql)--
------valid=True
----except Exception:
------print("Encoding Error")
------valid=False
----if valid:
------mass+=sql
------
outfile=r'new.txt'
open(outfile,mode='w',encoding='utf-8').write(mass)


line.decode('utf-8') 这样执行不会报错,只有输出时才报错,这是mysql的查询日志,100多兆
cnrting1469
2016-10-17 00:44:29 +08:00
用 len()<=0 就可以吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/146094

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX