python中的文件操作2

文件遍历

在Python中,遍历文件通常指的是逐行读取文件中的内容。这种方式对于处理大型文件特别有用,因为它不需要一次性将整个文件加载到内存中。下面是几种常见的遍历文件内容的方法:

1. 使用with语句和for循环

这是最推荐的方式,因为它会自动管理文件资源,并且代码可读性高。

file_path = 'example.txt'
with open(file_path, 'r') as file:for line in file:print(line.strip())  # 使用strip()去除每行末尾的换行符

2. 使用readline()方法

如果你想更细致地控制读取过程(例如,在某些条件下提前停止),可以使用readline()方法逐行读取。

file_path = 'example.txt'
with open(file_path, 'r') as file:while True:line = file.readline()if not line:  # 如果readline返回空字符串,则表示已到达文件末尾breakprint(line.strip())

3. 使用readlines()方法

虽然这个方法不是真正意义上的“遍历”(因为它会先读取整个文件到一个列表中),但如果你需要获取所有行并且内存足够大时,这也是一个方便快捷的选择。

file_path = 'example.txt'
with open(file_path, 'r') as file:lines = file.readlines()for line in lines:print(line.strip())

请注意,对于非常大的文件,第三种方法可能会消耗大量内存。通常情况下,第一种使用迭代器直接遍历文件对象的方式最为高效和优雅。

遍历二进制文件

如果你正在处理二进制数据(如图片或视频等),可能需要以块(block)来遍历:

file_path = './data/test_pic.png'# 复制文件到另一个文件
file_copy = open('./data/test_pic_copy.png', 'wb')with open(file_path, 'rb') as file:  # 注意模式为'rb'表示二进制模式读取while True:chunk = file.read(1024)  # 每次读取1024字节if not chunk:break# 处理chunk...file_copy.write(chunk)file_copy.close()

在处理文本或二进制数据时选择正确的遍历方式对于编写高效、可维护代码至关重要。

常用方法

当你使用open()函数打开一个文件后,会得到一个文件对象。这个文件对象提供了多种方法来帮助你读取、写入和操作文件。以下是一些常用的方法:

1. read(size=-1)

  • 读取并返回文件中最多size个字符(文本模式)或字节(二进制模式)。如果未指定size或指定为负数,则读取并返回整个文件。
with open('example.txt', 'r') as file:content = file.read()print(content)

2. readline(size=-1)

  • 读取直到遇到下一个换行符为止,并返回一行字符串。如果指定了size,则在达到size字符后停止。
with open('example.txt', 'r') as file:while True:line = file.readline()if not line:breakprint(line.strip())

3. readlines(hint=-1)

  • 读取并返回一个列表,其中包含文件中的行。如果提供了可选参数hint,则当读取的行数足够接近hint时停止。
with open('example.txt', 'r') as file:lines = file.readlines()
for line in lines:print(line.strip())

4. write(string)

  • 将字符串写入文件,并返回写入的字符数(文本模式)或字节数(二进制模式)。
with open('output.txt', 'w') as file:num_chars = file.write("Hello, World!")print(f"Written {num_chars} characters.")

5. writelines(lines)

  • 向文件写入一个字符串列表。此方法不会自动添加行结束符,因此如果需要,必须自己在每行末尾加上\n
lines = ["First line", "Second line", "Third line"]
with open('output.txt', 'w') as file:# 如果需要,在每行末尾加上\n来实现换行。lines_with_newlines = [f"{line}\n" for line in lines]file.writelines(lines_with_newlines)

6. seek(offset, whence=0) 和 tell()

  • seek() 改变当前文件操作位置。offset表示相对于whence位置的偏移量:0表示从文件开头计算(默认),1表示从当前位置计算,2表示从文件末尾计算。
  • tell() 返回当前在文件中的位置。
# 读取文件,将第5个字节替换为'XXX'
with open('./data/test22.txt', 'rb+') as file:  # 使用二进制模式作为示例# 移动到第五个字节(索引从0开始)file.seek(5)# 报告当前位置current_position = file.tell()print(f"Current position: {current_position}")# 修改当前位置的内容,并回到起始位置查看更改。# 注意:在文本模式下修改可能会因编码问题导致错误。new_content = b'XXX'  # 替换为三个字节的内容old_content = file.read(len(new_content))if old_content != new_content:# 回退字节以覆盖刚才读取的内容。seek_back = file.seek(-len(new_content), 1)  # 1表示当前位置write_byte = file.write(new_content)seek_start = file.seek(0)updated_content = file.read().decode("utf-8")print(updated_content)

原文件:
在这里插入图片描述

执行后:
在这里插入图片描述

7. flush()

  • 刷新内部缓冲区,将数据立即写入磁盘而不是等待自动刷新发生。这对于长时间运行且需要即时保存结果的程序很有用。
# 这里perform_event_processing是假定存在的处理事件函数,
# 实际使用时应替换为具体逻辑代码块或函数调用。
import threadingdef perform_event_processing():# 当前线程休眠3秒,模拟事件处理耗时threading.Event().wait(1000)print("Event processing started.")# 假设我们正在记录一些重要事件,希望确保即使程序崩溃也能保存日志信息。
log_file_path = './data/test_log_example.log'
event_log = open(log_file_path, 'a')
try:event_log.write("Event started.\n")# 注释掉下面这行代码,以观察不同,在线程休眠期间,日志是否会被写入文件event_log.flush()perform_event_processing()
except Exception as e:event_log.write(f"Error occurred: {e}\n")
finally:event_log.close()print("Event processing simulated.")

需求练习

示例文本文件

在Python中,文件操作主要涉及打开、读取、写入和关闭文件。
这是一门基础且重要的技能,因为它使得程序能够持久化数据,或者处理磁盘上的数据文件。
Python提供了一个内建的open函数用于文件的打开,以及文件对象提供的方法用于读取和写入。
使用open函数打开文件时,可以指定文件的路径和模式。模式指定了文件是用于读取、写入还是追加,以及文件是文本模式还是二进制模式。

初步实现

打开一个文本文件,将其中的’文件’字符替换为’文档’

with open('./data/test23.txt', 'r+') as file:text = file.read()replace_text = text.replace("文件", "文档")# 将当前操作位置移动到文件开头。这一步是必须的,因为在之前已经通过 .read() 方法将指针移动到了文件末尾。如果不重新定位到开始位置,接下来写入时会直接从末尾开始添加内容。file.seek(0)file.write(replace_text)# 防止替换后的文本比原始文本短,则新内容之后可能会保留旧数据残余部分。truncate 可以截断多余部分。file.truncate()

结果
在这里插入图片描述

注意

  • 这种方式在处理大型文本时可能不够高效,因为它一次性加载整个文本进内存。
  • 由于使用了’r+'模式,在不存在指定路径或者无法找到相应名称(test23.txt)时会抛出错误而非创建新文件。

改进实现

当处理大型文件时,一次性读取整个文件到内存确实可能导致效率低下甚至内存溢出。为了解决这个问题,可以采用分批处理的方法,逐行(或按一定大小的块)读取和写入文件。这样可以大大减少内存的使用。以下是一种改进方法,适用于逐行处理文本文件的场景:

分批处理替换文本

由于直接在原文件上进行逐行读写可能会复杂且易出错(特别是当替换后的文本长度与原文不同时),建议的方法是将修改后的内容写入一个临时文件,处理完成后再替换原文件。

import ossource_file_path = './data/test23.txt'
temp_file_path = './data/test23_temp.txt'with open(source_file_path, 'r', encoding='utf-8') as read_file, \open(temp_file_path, 'w', encoding='utf-8') as write_file:for line in read_file:modified_line = line.replace("文件", "文档")write_file.write(modified_line)# Replace the original file with the modified one
os.replace(temp_file_path, source_file_path)

解决方案解析

  1. 逐行读取:通过在with语句中同时打开源文件(用于读取)和临时文件(用于写入),可以逐行对源文件进行读取。这样就不需要一次性将整个文件内容加载到内存中。

  2. 逐行替换和写入:对于源文件的每一行,执行所需的替换操作,然后将结果写入临时文件。这个过程中,内存中仅需存储当前处理的行。

  3. 替换原文件:处理完成后,使用os.replace()方法将临时文件替换原文件。这个操作会自动删除原文件,并将临时文件重命名为原文件的名称。

注意事项

  • 这种方法适用于文本文件的逐行处理,可以有效减少内存消耗,特别是处理大文件时。
  • 完成替换操作后,原文件将被临时文件替代。确保在操作前做好相应的备份,以防数据丢失。
  • 如果处理过程中出现错误,可能需要手动清理临时文件或采取其他错误处理措施。
  • 对于更复杂的替换逻辑或大型二进制文件的处理,可能需要采用不同的策略。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

两天学会微服务网关Gateway-Gateway工作原理

锋哥原创的微服务网关Gateway视频教程: Gateway微服务网关视频教程(无废话版)_哔哩哔哩_bilibiliGateway微服务网关视频教程(无废话版)共计17条视频,包括:1_Gateway简介、2_Gateway工作原理、3…

ROS2学习(七) Foxy版本ros2替换中间件。

在ros2使用的过程中,一开始选用的foxy版本,后来发现,foxy版本的ros2有很多问题。一个是foxy版本已经停止维护了。另一个问题是这个版本有很多bug, 后续的版本在功能实现上做了很大的改动,甚至说进行了重写。修复的一些问题&#x…

【应用多元统计分析】--多元数据的描述和展示(R语言)

一元随机变量 我们用协方差来刻画两个变量的相关关系,这里指的是线性相关关系。 对于一元随机变量的可视化最简单的就是散点图,大致可以看出X和Y之间的相关关系。如果想更好的看X、Y之间的相关关系,可以画二维的散点图。 总结: 均…

Postman如何做接口测试?你居然还不知道

Postman如何做接口测试1:如何导入 swagger 接口文档 在使用 postman 做接口测试过程中,测试工程师会往界面中填入非常多的参数,包括 url 地址,请求方法,消息头和消息体等一系列数据,在请求参数比较多的情况…

[项目设计] 从零实现的高并发内存池(五)

🌈 博客个人主页:Chris在Coding 🎥 本文所属专栏:[高并发内存池] ❤️ 前置学习专栏:[Linux学习] ⏰ 我们仍在旅途 ​ 目录 8 使用定长内存池脱离new 9. 释放对象时不传大小 10.性能优化 10.1…

API协议设计的十种技术

文章目录 前言1.REST2. GraphQL3. gRPC (google Remote Procedure Calls)4.Webhook5. 服务端的事件发送——SSE(Servver - Sent Events )6. EDI(Electronic Data Interchange)7. 面向API 的事件驱动设计8. WebSocket9.简单对象访问协议(SOAP)10. Message Queuing Telemetry …

vue系列——vscode,node.js vue开发环境搭建

第一步安装node.js 推荐使用nvm进行node.js 的安装 nvm(Node.js version manager) 是一个命令行应用,可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 可以去网上查找相关版本 我这里使用 nvm-setu… 链接:https://pan.baidu.com/s/1UEUtmzw5x…

饮料换购 刷题笔记

直接开个计数器mask 每当饮料现存数-1&#xff1b; cnt;且mask; 一旦mask达到3 饮料现存数 计数器清零3 代码 #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int main(){ int n; …

【STM32】HAL库 CubeMX教程---基本定时器 定时

目录 一、基本定时器的作用 二、常用型号的TIM时钟频率 三、CubeMX配置 四、编写执行代码 实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM6&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、基本定时器的作用 基本定时器&#xff0c;主要用于实现定时和计数功能…

【重要!!退税!退税!】一年一度个人所得税综合年度汇算开始了!

目录标题 如何退税&#xff1f;2023年度个人所得税综合所得汇算清缴操作指南汇算准备标准申报 退税骗局&#xff1f;1.“您有一笔退税待领取”骗局2.“专业人员帮你多退税”骗局3.“诱导填报虚假个税信息”骗局4.“税务稽查人员联系你”骗局 如何退税&#xff1f; 2023年度个人…

Java引用传递及基本应用

在 Java 中&#xff0c;传递参数的方式主要有两种&#xff1a;值传递&#xff08;传递的是对象的引用值&#xff09;和引用传递。本教程将重点介绍 Java 中的引用传递以及其基本应用。 1. 引用传递概念 在 Java 中&#xff0c;所有的方法参数都是通过值传递的。对于对象类型的…

腾讯云服务器和阿里云服务器价格测评_2024年费用大PK

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器61元一年&#xff0c;2核2G3M、2核4G、4核8G、4核16G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配…

[数据结构]OJ用队列实现栈

225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 官方题解&#xff1a;https://leetcode.cn/problems/implement-stack-using-queues/solutions/432204/yong-dui-lie-shi-xian-zhan-by-leetcode-solution/ 首先我们要知道 栈是一种后进先出的数据结构&#xff0c…

阿珊详解Vue路由的两种模式:hash模式与history模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

《TCP/IP详解 卷一》第15章 TCP数据流与窗口管理

目录 15.1 引言 15.2 交互式通信 15.3 延时确认 15.4 Nagle 算法 15.4.1 延时ACK与Nagle算法结合 15.4.2 禁用Nagle算法 15.5 流量控制与窗口管理 15.5.1 滑动窗口 15.5.2 零窗口与TCP持续计时器 15.5.3 糊涂窗口综合征 15.5.4 大容量缓存与自动调优 15.6 紧急机制…

力扣刷题Days11第二题--141. 环形链表(js)

目录 1,题目 2&#xff0c;代码 2.1快慢指针 2.2&#xff0c;哈希表 3&#xff0c;学习与总结 3.1自己尝试写快慢指针 反思 1,题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&…

14:00面试,15:00就出来了,问的问题过于变态了。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到2月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

C++调用lua函数

C 调用Lua全局变量(普通) lua_getglobal(lua, "width");int width lua_tointeger(lua,-1);lua_pop(lua,1);std::cout << width << std::endl;lua_close(lua); 这几行代码要放到lua_pcall(lua, 0,0,0);之后才可以. C给lua传递变量 lua_pushstring(lua, …

抖音商家短视频直播流量变现运营SOP地图

【干货资料持续更新&#xff0c;以防走丢】 抖音商家短视频直播流量变现运营SOP地图 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 抖音运营资料合集&#xff08;完整资料包含以下内容&#xff09; 目录 【提升短视频运营效率的专业指南】 高效运营&#xf…