利用Python filestream实现文件流读

news2024/11/30 3:48:16

在 Python 中,文件流(filestream)操作通过内置的 open() 函数实现,它提供了对文件的读取、写入、以及流控制的支持。常见的文件模式包括:

  • r:只读模式(默认)。
  • w:写入模式(会覆盖已有内容)。
  • a:追加模式。
  • r+:读写模式。

下面介绍如何使用文件流进行基本的文件操作,以及如何控制文件流读取(如逐行读取、分块读取等)。

在这里插入图片描述

1、问题背景

在编写一个编译器时,需要逐个字符地读取文件中的内容。如果遇到 “/” 后跟另一个 “/”,则将把其余的行视为注释。使用 file.read(1) 每次读取一个字符。但是,如果查找到 “/” 后面跟着不是 “/” 的字符,有没有办法将文件流向后移动一个字符,以免丢失该字符?

以下是相关代码:

def tokenType(self):
    # PAGE 108
    if (self.current == '{' or self.current == '}' or self.current == '(' or self.current == ')' or self.current == '[' or self.current == ']' or self.current == '.' or self.current == ',' or self.current == ';' or self.current == '-' or self.current == '*' or self.current == '/' or self.current == '&' or self.current == '|' or self.current == '<' or self.current == '>' or self.current == '=' or self.current == '~'):
        if (self.current == '/'):
            next = self.file.read(1)
            if (next == '/'):
                while (next != "\n"):
                    next = self.file.read(1)
                return "IGNORE"
            if (next == '*'):
                while (True):
                    next = self.file.read(1)
                    if (next == '*'):
                        next = self.file.read(1)
                        if (next == '/'):
                            break
                return "IGNORE"
            else:
                return "SYMBOL"
        return "SYMBOL"
    elif (self.current == " " or self.current == "\n"):
        return "IGNORE"
    elif (self.current == "'"):
        while(next != "'"):
            self.current = self.current + next
        return "STRING_CONST"
    elif (type(self.current) == int):
        next = self.file.read(1)
        while(next != " "):
            self.current = self.current + next
        return "INT_CONST"
    else:
        next = self.file.read(1)
        while(next != " " and next != ""):
            self.current = self.current + next
            next = self.file.read(1)
        if (self.current == 'class' or self.current == 'constructor' or self.current == 'function' or self.current == 'method' or self.current == 'field' or self.current == 'static' or self.current == 'var' or self.current == 'int' or self.current == 'char' or self.current == 'boolean' or self.current == 'void' or self.current == 'true' or self.current == 'false' or self.current == 'null' or self.current == 'this' or self.current == 'let' or self.current == 'do' or self.current == 'if' or self.current == 'else' or self.current == 'while' or self.current == 'return'):
            return "KEYWORD"
        else:
            return "IDENTIFIER"

My problem seems to be when I have something like 10/5 and my program checks to see if the next character is a "/". Then on the next pass through my character interpreting function, the 5 has already been removed when it was checking for a comment.
So, is there any way I can get a character from a file stream without it being "removed" from the stream or is there a way I can move it back a character when I hit a case like this?

2、解决方案

  • 第一种方法: 使用 file.seek() 函数调整文件流位置

    file.seek() 可以将文件流指针定位到文件中的特定位置。在处理完一个字符后,可以使用 file.seek() 将流指针向前移动一个字符,以便在下次读取时能够读取该字符。

    def tokenType(self):
        # PAGE 108
        if (self.current == '{' or self.current == '}' or self.current == '(' or self.current == ')' or self.current == '[' or self.current == ']' or self.current == '.' or self.current == ',' or self.current == ';' or self.current == '-' or self.current == '*' or self.current == '/' or self.current == '&' or self.current == '|' or self.current == '<' or self.current == '>' or self.current == '=' or self.current == '~'):
            if (self.current == '/'):
                next = self.file.read(1)
                if (next == '/'):
                    while (next != "\n"):
                        next = self.file.read(1)
                    return "IGNORE"
                if (next == '*'):
                    while (True):
                        next = self.file.read(1)
                        if (next == '*'):
                            next = self.file.read(1)
                            if (next == '/'):
                                break
                    return "IGNORE"
                else:
                    self.file.seek(-1, 1)  # 将文件流指针向前移动一个字符
                    return "SYMBOL"
            return "SYMBOL"
        elif (self.current == " " or self.current == "\n"):
            return "IGNORE"
        elif (self.current == "'"):
            while(next != "'"):
                self.current = self.current + next
            return "STRING_CONST"
        elif (type(self.current) == int):
            next = self.file.read(1)
            while(next != " "):
                self.current = self.current + next
            return "INT_CONST"
        else:
            next = self.file.read(1)
            while(next != " " and next != ""):
                self.current = self.current + next
                next = self.file.read(1)
            if (self.current == 'class' or self.current == 'constructor' or self.current == 'function' or self.current == 'method' or self.current == 'field' or self.current == 'static' or self.current == 'var' or self.current == 'int' or self.current == 'char' or self.current == 'boolean' or self.current == 'void' or self.current == 'true' or self.current == 'false' or self.current == 'null' or self.current == 'this' or self.current == 'let' or self.current == 'do' or self.current == 'if' or self.current == 'else' or self.current == 'while' or self.current == 'return'):
                return "KEYWORD"
            else:
                return "IDENTIFIER"
    
    My problem seems to be when I have something like 10/5 and my program checks to see if the next character is a "/". Then on the next pass through my character interpreting function, the 5 has already been removed when it was checking for a comment.
    So, is there any way I can get a character from a file stream without it being "removed" from the stream or is there a way I can move it back a character when I hit a case like this?
    
  • 第二种方法: 使用 Python 的 io.StringIO()

    io.StringIO() 类可以创建一个文件对象,该对象将字符串作为输入。这样,就可以将字符串作为文件流来处理。当需要将文件流指针向前移动时,可以使用 io.StringIO()seek() 方法来调整指针位置。

    import io
    
    def tokenType(self):
        string_io = io.StringIO(self.file.read())  # 将文件内容作为字符串读入
        while True:
            char = string_io.read(1)
            if char == '{' or char == '}' or char == '(' or char == ')' or char == '[' or char == ']' or char == '.' or char == ',' or char == ';' or char == '-' or char == '*' or char == '/' or char == '&' or char == '|' or char == '<' or char == '>' or char == '=' or char == '~':
                if char == '/':
                    next = string_io.read(1)
                    if next == '/':
                        while next != "\n":
                            next = string_io.read(1)
                        return "IGNORE"
                    if next == '*':
                        while True:
                            next = string_io.read(1)
                            if next == '*':
                                next = string_io.read(1)
                                if next == '/':
                                    break
                        return "IGNORE"
                    else:
                        string_io.seek(-1, 1)  # 将文件流指针向前移动一个字符
                        return "SYMBOL"
                return "SYMBOL"
            elif char == " " or char == "\n":
                return
    

总结

  • 按行读取:适用于逐行处理大文件。
  • 分块读取:适用于内存敏感的操作,尤其是处理超大文件时。
  • 文件指针控制:通过 seek()tell() 可以实现随机访问和流控制。
  • 安全文件操作:使用 with 关键字和异常处理可以确保文件安全、正确地被打开和关闭。

这些方法可以帮助你高效地控制和处理文件流,尤其是在处理大文件时,能够大大优化内存使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2215563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用Python构建动态折线图:实时展示爬取数据的指南

背景/引言 随着大数据和人工智能的不断发展&#xff0c;实时数据分析变得越来越关键&#xff0c;尤其是在金融市场中。股市数据的实时可视化可以帮助投资者快速做出决策&#xff0c;避免错失良机。Python 凭借其强大的数据处理能力和丰富的可视化库&#xff0c;成为分析和展示…

你不是算法工程师,就可以不了解AI大模型技术吗?

身处人工智能的大浪潮之中&#xff0c;除了算法工程师&#xff0c;其他的角色也都应当对人工智能大模型技术有一定的了解。所以&#xff0c;笔者将针对“什么是人工智能&#xff1f;”“非技术人员对于人工智能大模型的理解存在哪些门槛&#xff1f;”等问题与大家分享自己的见…

项目集成工作流,走审批流程,activiti,springboot,集成工作流,业务审批,驳回,会签,流程设计

前言 activiti工作流引擎项目&#xff0c;企业erp、oa、hr、crm等企事业办公系统轻松落地&#xff0c;一套完整并且实际运用在多套项目中的案例&#xff0c;满足日常业务流程审批需求。 项目源码配套文档获取&#xff1a;本文末个人名片直接获取。 一、项目形式 springboot…

健康补充维生素

在快节奏的现代生活中&#xff0c;健康养生已成为我们不可忽视的重要议题。而提及养生&#xff0c;维生素这一关键词往往跃然纸上&#xff0c;它们作为人体不可或缺的微量营养素&#xff0c;对维持生命活动、促进健康起着至关重要的作用。今天&#xff0c;就让我们深入探讨如何…

中小型医院网站:Spring Boot框架详解

5 系统实现 5.1 用户功能模块的实现 用户进入本系统可查看系统信息&#xff0c;包括首页、门诊信息、药库信息以及系统公告信息等&#xff0c;系统前台主界面展示如图5-1所示。 图5-1系统前台主界面图 5.1.1用户登录界面 用户要想实现预约挂号功能&#xff0c;必须登录系统&a…

修改Linux的IP地址

方法一&#xff08;特点&#xff1a;命令执行后&#xff0c;IP立即修改&#xff0c;但重启后会恢复原来的IP地址&#xff09; 1.含义&#xff1a; inet ip地址 netmask 子网掩码 broadcast 广播地址 inet 192.168.44.129 netmask 255.255.255.0 broadcast 192.168.1.255 …

仅涨粉1.3万、清空橱窗,贾跃亭直播带货这么快就哑火了?

还记得上周&#xff0c;贾跃亭声势浩大的做了个重大决定&#xff0c;也就是几个月前说的要个人IP商业化这盘菜端到了直播带货行业。‍‍ 当时&#xff0c;说他口气大&#xff0c;那真是一点也不小&#xff0c;比如要给中美人民、中美零售业、中美产品、中美品牌&#xff0c;搭一…

LeNet-5(论文复现)

LeNet-5&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 LeNet-5&#xff08;论文复现&#xff09;概述LeNet-5网络架构介绍训练过程测试过程使用方式说明 概述 LeNet是最早的卷积神经网络之一。1998年&#xff0c;Yann LeCun第一次将LeN…

站在用户视角审视:以太彩光与PON之争

作者:科技作家-郑凯 园区,是企业数字化转型的“中心战场”。 云计算、大数据、人工智能等数智化技术在园区里“战火交织”;高清视频、协同办公,智慧安防等大量创新应用产生的海量数据在园区内“纵横驰骋”;加上大量的IOT和智能化设备涌入“战场”,让园区网络面对着难以抵御的…

基于YOLOv9的空中飞鸟识别检测系统(附项目源码和数据集下载)

项目完整源码与模型 YOLOv9实现源码&#xff1a;项目完整源码及教程-点我下载YOLOv5实现源码&#xff1a;项目完整源码及教程-点我下载YOLOv7实现源码&#xff1a;项目完整源码及教程-点我下载YOLOv8实现源码&#xff1a;项目完整源码及教程-点我下载数据集&#xff1a;空中飞…

等保测评的技术要求与管理要求详解

等保测评&#xff0c;即网络安全等级保护测评&#xff0c;是根据《中华人民共和国网络安全法》、《信息安全技术网络安全等级保护基本要求》等相关法规和标准&#xff0c;对信息系统的安全性进行评估的过程。等保测评分为技术要求和管理要求两大方面&#xff0c;旨在确保信息系…

外包干了5天,技术明显退步

我是一名本科生&#xff0c;自2019年起&#xff0c;我便在南京某软件公司担任功能测试的工作。这份工作虽然稳定&#xff0c;但日复一日的重复性工作让我逐渐陷入了舒适区&#xff0c;失去了前进的动力。两年的时光匆匆流逝&#xff0c;我却在原地踏步&#xff0c;技术没有丝毫…

PicoQuant GmbH公司Dr. Christian Oelsner到访东隆科技

昨日&#xff0c;德国PicoQuant公司的光谱和显微应用和市场专家Dr.Christian Oelsner莅临武汉东隆科技有限公司。会议上Dr. Christian Oelsner就荧光寿命光谱和显微技术的最新研究和应用进行了深入的交流与探讨。此次访问不仅加强了两家公司在高科技领域的合作关系&#xff0c;…

成都爱尔李晓峰主任讲解“寒”已至,眼需“养”

温度逐渐走低&#xff0c;寒冷空气的到来带走夏季闷热潮湿&#xff0c;也带走了空气中的水分&#xff0c;环境变得干燥&#xff0c;眼睛水分蒸发加快&#xff0c;十分容易造成眼部不适&#xff0c;干眼患者尤其需要注意&#xff01; 有干眼问题的患者&#xff0c;在这样的天气下…

案例实践 | 以长安链为坚实底层,江海链助力南通民政打造慈善应用标杆

案例名称-江海链 ■ 实施单位 中国移动通信集团江苏有限公司南通分公司、中国移动通信集团江苏有限公司 ■ 业主单位 江苏省南通市民政局 ■ 上线时间 2023年12月 ■ 用户群体 南通市民政局、南通慈善总会等慈善组织及全市民众 ■ 用户规模 全市近30家慈善组织&#…

【网络安全】漏洞案例:提升 Self-XSS 危害

未经许可,不得转载。 文章目录 Self-XSS-1Self-XSS-2Self-XSS-1 目标应用程序为某在线商店,在其注册页面的First Name字段中注入XSS Payload: 注册成功,但当我尝试登录我的帐户时,我得到了403 Forbidden,即无法登录我的帐户。 我很好奇为什么我无法登录我的帐户,所以我…

【unity框架开发起步】一些框架开发思维和工具类封装

文章目录 前言一、Editor操作二、快捷导出unity包三、快捷打开存储目录四、封装transform操作1、localPosition赋值简化2、封装修改transform.localPosition X Y Z3、封装transform.localPosition XY、XZ 和YZ4、Transform 重置 五、封装概率函数六、方法过时七、partial 关键字…

STM32_实验2_printf函数重定向输出

掌握串口通信&#xff0c;并将 printf 函数重定向到串口输出。 USART1 global interrupt 的使能与不使能对系统的影响主要体现在如何处理串口通信事件上&#xff0c;如数据接收和发送的方式。这些不同的配置会直接影响系统的效率、响应时间以及资源的使用。 配置printf函数使用…

递归查找子物体+生命周期函数

递归查找子物体 相关代码&#xff1a; Transform FindChild(string childName, Transform parent){if (childName parent.name) {return parent;}if (parent.childCount < 1){return null;}Transform obj null;for(int i 0; i < parent.childCount; i){Transform t …

Hbuilder如何修改px转rpx的比例如图

mac系统点击hbuilderX图标如图&#xff1a; 打开偏好设置后选择语言服务配置&#xff0c;在px转rpx中设置对应比例&#xff0c;例如设计稿是375那就是0.5&#xff0c;设计稿是750就是1&#xff0c;公式按照设计稿宽度/750 得出比例