V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yakczh
V2EX  ›  问与答

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

  •  
  •   yakczh · 2014-11-13 10:10:54 +08:00 · 8974 次点击
    这是一个创建于 3454 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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怎么样检测读到文件尾?
    14 条回复    2016-10-17 00:44:29 +08:00
    Sylv
        1
    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
        2
    yakczh  
    OP
       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
        3
    yakczh  
    OP
       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
        4
    Jaylee  
       2014-11-13 12:59:11 +08:00
    mode="rb"
    yakczh
        5
    yakczh  
    OP
       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
        6
    Sylv  
       2014-11-13 16:06:24 +08:00 via iPhone
    @yakczh 什么特殊字符?我感到困惑的是,如果这些特殊字符也是用utf8正确编码的,那为什么用utf8去读取会出错?
    可以把这个文件传网盘之类的,贴上看看吗?

    关于 readine(),你去看文档就会知道如果返回空字符串就说明到文件尾了,所以用 if not line 来判断是可以的。你说这样会出异常,出的是什么异常?
    clino
        7
    clino  
       2014-11-13 16:29:14 +08:00
    没错,我首先想到的就是楼上sylv的这种方法,判断是否空串就行了,这种方法不一定要readline吧,read也行
    staticor
        8
    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
        9
    lcqtdwj  
       2014-11-13 16:56:06 +08:00
    我觉得你问题解决层面不对,应该在数据来源解决。
    yakczh
        10
    yakczh  
    OP
       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
        11
    Sylv  
       2014-11-13 17:17:33 +08:00 via iPhone
    @yakczh 你贴文件内容上来没用啊,得传整个文件上来才好知道是哪里编码出问题了。
    我赞同 lcqtdwj 说的,应该从数据源来解决问题。我理解是这个文件中有部分字符不是用utf8编码的,所以读取出错。可以试着把源文件全部内容转换为utf8编码后再读取。

    如果按你的想法,应该 staticor 的方法是正解。
    lcqtdwj
        12
    lcqtdwj  
       2014-11-13 21:41:29 +08:00
    @yakczh 在表单存入数据库之前应该检查request的charset,根据charset编码转换为适当的编码再存入数据库
    yakczh
        13
    yakczh  
    OP
       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
        14
    cnrting1469  
       2016-10-17 00:44:29 +08:00
    用 len()<=0 就可以吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4566 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 04:04 · PVG 12:04 · LAX 21:04 · JFK 00:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.