python 创建文件 a+_Python文件操作

一. 操作文件的三个步骤: 打开文件, 读写, 回收OS资源

1. 方式一: 打开文件, 读写, 回收OS资源

f = open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") # t读写文件的格式为字符串,open返回值文件对象/文件句柄,是程序的变量值

data = f.read() # 硬盘上的文件内容读到内存中,OS根据指定的encoding把二进制数转成t(unicode字符串)给程序,t仅限文本文件

print(data, type(data))

f.close() # close回收OS资源,close后不能再read,文件对象是程序的变量值,是程序的资源,仍然存在

2. 方式二: 上下文管理 with 会自动调用f.close(), f1.close(), f2...

with open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") as f, \

open(r"Y:\new\b.txt", mode="rt", encoding="utf-8") as f1:

pass # 也可以用...

二. 文件的打开模式

1. 控制文件读写操作的模式: r只读, w只写,擦写, a只追加写, +加上原没有的操作, r+, w+, a+: 读写

1.1 r: 只读, 不可写, 默认模式, 指针在文件开头

with open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") as f:

print(f.readable()) # True

print(f.writable()) # False

1.2 w: 只写, 不可读, 创建一个新文档, 同名文件不存在则为创建, 同名文件存在则覆盖, 指针跳到文件开头

with open(r"Y:\new\b.txt", mode="wt", encoding="utf-8") as f:

f.write("你好\nHello World.")

f.write("打开文件不关的情况下,指针跟着移动,后续新写入的内容则是追加.但是文件关了重新打开,再写=擦写")

1.3 a: 只追加写,不可读,文件不存在则新建一个空文件;文件存在则不清空,无论是不是重新打开或关了,文件指针都跳到文件末尾,追加写入新内容

1.4 r+, w+, a+: 读写

2. 控制文件读写内容的模式, t,b须和r,w,a连用

2.1 t: 默认, 文本格式, 读写都是str字符串, 数字不可以, 仅限文本文件, 必须指定encoding参数

2.2 b: 原生格式, 读写都是bytes为单位, 能用于所有文件, 一定不能指定encoding参数

with open(r"Y:\new\a.txt", mode="wb") as f:

f.write("原生格式写入新内容".encode("utf-8"))

3. 案例: 文件copy程序

src_file = input("源文件路径: ").strip()

dst_file = input("目标文件路径: ").strip()

with open(r"%s" % src_file, mode="rb") as f1, \

open(r"%s" % dst_file, mode="wb") as f2:

3.1 方法一: 一次性读入内存

data = f1.read()

f2.write(data)

3.2 方法二: 逐行读取写入

for line in f1:

f2.write(line)

三. 文件内指针移动: seek是无IO操作的移动, read是有IO操作的被动移动

file.seek(移动的字节个数, 三种模式) # 3种模式都以字节为移动单位

1. 三种模式:

1.1 模式 0 : 从文件开头为起点,f.seek(3, 0)从头往右移动3个字节

1.2 模式 1 : 从当前指针所在的位置,f.seek(6, 1)前面停在第3字节,现停在第9字节

1.3 模式 2 : 从文件末尾为起点,f.seek(-6, 2)从末尾往左移6字节,正数右移,负数左移

2. 三种模式适用范围:

2.1 mode="t"模式: seek只能用 模式 0, 而另一种移动read(n)中n,只有mode="t"模式下,代表字符个数

with open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") as f: # 文件内容:hello你好

print(f.read(6)) # 打印: hello你 ,以字符为单位,中英文都是一个字符

2.2 mode="b"模式: seek都可用 模式 0, 1, 2, seek和read(n)中n都代表字节个数

with open(r"Y:\new\a.txt", mode="rb") as f: # 文件内容:hello你好

print(f.read(6)) # 打印: b'hello\xe4' ,以字节为单位,utf-8中,中文3字节,英文1字节

f.seek(0, 2) # 指针跳到末尾

print(f.tell()) # tell获取从文件开头到当前位置的总字节数

3. 示例: 模拟写tail -f access.log

3.1 测试程序写入日志

import time

with open('access.log', mode='at', encoding='utf-8') as f:

f.write("%s %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S %p"), "程序写的日志内容"))

3.2 模拟写tail -f 查看日志

import time

with open('access.log', mode='rb') as f:

f.seek(0, 2)

while True:

line = f.readline() # readline每次读一行

if len(line) == 0: # 没有日志的时候, 稍微等待, 减少负载开销

time.sleep(0.5) # 死循环会不停调用,负载会升高

else:

print(line.decode('utf-8'), end='') # 原日志中\n,打印默认也有,会有两个\n去掉一个

四. 操作文件的方法

1. f.read(n) 从当前位置读到末尾,只有mode="t"模式下,read(n)中n代表字符个数

2. f.readlines() rt模式,以行为单位读取文本,存入列表['hello你好\n','l2\n','l3']

3. f.writelines("hello") wt模式, 循环分别写入5个字母, 而f.write("hello")一次写入

with open(r"Y:\new\a.txt", mode="wt", encoding="utf-8") as f:

lines = ["aa\n", "bb\n", "cc\n"]

for line in lines: # 这两行效果等于f.writelines(lines), 实质就是for循环取值

f.write(line)

4. f.flush() 内存数据刷入硬盘

5. f.truncate(size) 截断,从开头保留n个字节,后面全删,是写操作,故要r+,a模式

with open(r"Y:\new\a.txt", mode="r+t", encoding="utf-8") as f:

f.truncate(3)

五. 修改文件的方式

1. 方式一: 硬盘文件一次性读入内存, 内存中修改完, 再覆盖原文件,不额外占用硬盘空间, 过多占用内存

with open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") as f1:

data = f1.read()

res = data.replace("source", "target")

with open(r"Y:\new\a.txt", mode="wt", encoding="utf-8") as f2:

f2.write(res)

2. 方式二: 逐行读源文件,内存中修改后,逐行写入临时文件,删除源,临时文件重命名,额外占用硬盘空间, 节省内存

import os

with open(r"Y:\new\a.txt", mode="rt", encoding="utf-8") as f1, \

open(r"Y:\new\.a.txt.swp", mode="wt", encoding="utf-8") as f2:

for line in f1:

f2.write(line.replace("source", "target"))

os.remove(r"Y:\new\a.txt")

os.rename(r"Y:\new\.a.txt.swp", r"Y:\new\a.txt")

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值