文件处理
什么是文件
定义:
- 文件是操作系统提供给应用程序或者说用户的一种操作硬盘功能
为何要处理文件
为了操作硬盘,读取文件
如何处理文件
- 1、打开文件,得到文件句柄并赋值给变量
- 2、通过文件句柄操作文件
- 3、关闭文件
#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
#2. 通过句柄对文件进行操作
data=f.read()
#3. 关闭文件
f.close()
with上下文管理
# 1、在执行完子代码块后,with 会自动执行f.close()
with open('a.txt','w') as f:
pass
# 2、可用用with同时打开多个文件,用逗号分隔开即可
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
data = read_f.read()
write_f.write(data)
文件操作模式
控制文件读写内容
-
t:无论读写都是以字符串问单位的,必须指定encoding
-
b:无论读写都是bytes为单位的
控制文件读写操作
r(默认):只读模式
w:只写
a:只写,追加
r:不存在则报错,存在读取文件则指针至于文件开头
with open ('a.txt',mode='rt',encoding='utf-8')as f:
print(f.read())
w:如果文件不存在,则创建新的空文档,如果存在,则覆盖重写
with open ('a.txt',mode='w',encoding='utf-8')as f:
f.wrinte('你好\n')
f.wrinte('你好2\n')
f.wrinte('你好3\n')
#强调:
# 1 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面
# 2 如果重新以w模式打开文件,则会清空文件内容
a:如果文件不存在,创建空文档,如果存在,文件不清空,文件指针在末尾
with open('c.txt',mode='at',encoding='utf-8') as f:
f.write("你好啊1\n")
f.write("你好啊2\n")
f.write("你好啊3\n")
print(f.read()) # 报错
w 模式与 a 模式的异同:
1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后
控制文件读写内容的模式
前提:t/b模式都不可单独使用,必须配合r\w\a之一结合使用
t:是默认的,为文本模式
文件打开模式
with open(r'1.mp4',mode='rb') as f:
data = f.read()
print(data)#占用内存,不提倡使用
for line in f: #将一行一行读取文件内容
print(line)
b:是二进制模式。
可读可写模式(很少用到)
with open('a.txt',mode='r+t',encoding='utf-8') as f:
# f.write('次卧')
f.write('h')
复制文件
#方案一:
with open(1.mp4, mode ='rb') as f1, open (r'D:\1.mp4',mode='wb') as f2:
for linr in f1:
f2.write(line)
#方案二:
path1 = input('输入要复制的文件路径>>:')
path2 = input(' 请输入放置文件路径>>:')
with open(path1, mode='rt') as f1, open(path2, mode='wt') as f2:
for line in f1:
f2.write(line)
修改文件的两种方式
#方案一:不适用于文件过大,文件小,可以使用
with open('b.txt' ,mode='rt',encoding='utf-8')
as f:
data = f1.read()
res = data.replace('egon','EGON')
with open('b.txt' ,mode='rt',encoding='utf-8')
as f2:
f2.write(res)
#方案二:
import os
with open('b.txt', mode='rt', encoding='utf-8')as f1, open('.b.txt.swp', mode='wt', encoding='utf-8')as f2:
for line in f1:
f2.write(line.replace('EGON','egon'))
os.remove('b.txt')
os.rename('.b.txt.swp', 'b.txt')
练习
#注册
inp_user = input("请输入用户名:>>").strip()
inp_pwd = input("请输入密码:>>").strip()
inp_money = input('请输入余额:>>').strip()
with open('db.txt', mode='a', encoding='utf-8') as f:
f.write("{}:{}:{}\n".format(inp_user,inp_pwd,inp_money))
# 登录
username = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
with open('db.txt',mode= 'r', encoding='utf-8') as f:
for line in f:
user, pwd = line.strip('\n').split(':')
if username == user and password == pwd:
print('登录成功')
break
else:
print('账号密码错误!')
# 转账
to_user = input('请输入转账账号户:>>').strip()
transfer_account = input('请输入转账金额:>>').strip()
with open('db.txt', mode='rt', encoding='utf-8')as f1, open('.db.txt.swp', mode='wt', encoding='utf-8')as f2:
for line in f1:
user, pwd, transfer_account = line.strip('\n').split(':')
if user == 'tom':
transfer_account = int(transfer_account) - 100
elif user == 'cc':
transfer_account = int(transfer_account) + 100
line = ("{}:{}:{}\n".format(user, pwd, transfer_account))
f2.write(line)
os.remove('db.txt')
os.rename('.db.txt.swp', 'db.txt')
#db.txt
tom:123:9900
tany:123:100000
cc:123:10100
文件读写的其他方式
close() | 关闭文件。 |
---|---|
detach() | 从缓冲区返回分离的原始流(raw stream)。 |
fileno() | 从操作系统的角度返回表示流的数字。 |
flush() | 刷新内部缓冲区。 |
isatty() | 返回文件流是否是交互式的。 |
read() | 返回文件内容。 |
readable() | 返回是否能够读取文件流。 |
readline() | 返回文件中的一行。 |
readlines() | 返回文件中的行列表。 |
seek() | 更改文件位置。 |
seekable() | 返回文件是否允许我们更改文件位置。 |
tell() | 返回当前的文件位置。 |
truncate() | 把文件调整为指定的大小。 |
writeable() | 返回是否能够写入文件。 |
write() | 把指定的字符串写入文件。 |
writelines() | 把字符串列表写入文件。 |
-
readable :检查文件是否可读
-
readline:返回文件中的一行
-
readlines:返回文件中的行列表
with open('b.txt',mode='rt',encoding='utf-8') as f:
print(f.readable())
print(f.readline())
print(f.readline())
lines = f.readlines()
print(lines[0])
-
writable:返回是否能够写入文件
-
writelines:把字符串列表写入文件
-
flush():刷新内部缓冲区
with open('b.txt', mode='wt', encoding='utf-8') as f: print(f.writable()) #返回是否能够写入文件 lines = ['你好\n', '我好\n', '大家好\n'] for line in lines: f.write(line) f.writelines(lines) #把字符串列表写入文件 f.write('1111\n222\n333\n') f.write('hello') f.writelines('hello') f.flush()
控制文件指针移动
前提:只有t模式下的read(n)的n代表的是字符个数,除此以外都代表字节个数
with open('b.txt',mode='rt',encoding='utf-8') as f: print(f.read(4)) #读取到文件4个字节的内容 with open('b.txt',mode='rb') as f: print(f.read(3).decode('utf-8'))
f.seek(移动的字节个数,模式)
模式:
-
0:参照文件开头,只有0模式可以在t下使用,其他的都只能在b下使用
with open('b.txt',mode='rt',encoding='utf-8') as f: f.seek(6,0) print(f.tell()) #6 #指针从第0位开始,以后往后移6位
-
1:参照指针当前所在的位置,只能在b下使用
with open('b.txt',mode='rb') as f: f.seek(3,1) f.seek(6,1) print(f.tell()) #9 #当指针走到第3个字节是,停下,再从第三个字节开始往后走6个字节,所有总共走了9个字节
-
2:参照指针文件末尾,通常是倒着移动,只能在b下使用
with open('b.txt',mode='rb') as f: f.seek(-5,2) f.seek(-8,2) print(f.tell()) print(f.read().decode('utf-8')) #6 #啊hello
-