You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python TextIOWrapper读取文件遇特殊行中断无法读取完整文件

解决方案

问题原因

读取中断并非第92行文本本身存在特殊转义字符,通常是该行前后混入了\x1a(Windows平台Ctrl+Z对应的文件结束标识),Python默认会将该字符识别为EOF终止读取。你之前使用二进制模式未生效,是因为调用readlines()全量加载时没有对异常字节做容错处理,遇到伪造的EOF标识就会截断读取流程。

方案1:正向容错读取(需读取文件靠前内容时使用)

不要用readlines()一次性加载全量内容,打开文件时指定errors='ignore'忽略解码异常,直接迭代文件对象逐行读取即可,遇到异常字节会自动跳过不会中断:

import os

txt_file = os.path.join(dir_register, 'messag')
cpu_time = None

with open(txt_file, 'r', encoding='utf-8', errors='ignore') as f:
    for line in f:
        if 'Total CPU time' in line:
            cpu_time = float(line.split()[4])
            break # 找到目标后直接退出,无需读取后续内容

如果必须用二进制模式,读取后对每一行手动指定errors='ignore'解码即可,效果一致。

方案2:尾部反向读取(仅提取末尾CPU时间时优先用)

由于目标数据在文件近尾部,反向读取不需要遍历前面的内容,可完全绕开第92行的异常段,读取效率更高:

import os

txt_file = os.path.join(dir_register, 'messag')
cpu_time = None
block_size = 2048 # 每次从尾部读取2KB块,可根据实际行长度调整

with open(txt_file, 'rb') as f:
    f.seek(0, os.SEEK_END)
    file_size = f.tell()
    prev_tail = b''

    # 从尾往前逐块扫描
    for block_idx in range(file_size // block_size + 1):
        read_pos = max(file_size - (block_idx + 1) * block_size, 0)
        f.seek(read_pos)
        current_block = f.read(block_size) + prev_tail
        lines = current_block.split(b'\n')

        # 倒序遍历当前块的行,找目标字段
        for line in reversed(lines):
            if b'Total CPU time' in line:
                cpu_time = float(line.split()[4])
                break
        if cpu_time is not None:
            break
        # 保存块首截断的不完整行,和下一个读取块拼接
        prev_tail = lines[0]

方案选择建议

  • 若后续还需提取文件前部的其他数据,选用方案1即可,errors='ignore'参数已经能覆盖绝大多数异常字符导致的读取中断问题;
  • 若仅需提取CPU时间字段,优先选方案2,不需要处理文件前部的异常内容,大文件下速度优势更明显。

内容的提问来源于stack exchange,提问作者SirFritz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:39:22