文件是操作系统提供给用户或者应用程序操作硬盘的接口,是一个虚拟概念,用户或应用程序通过文件将数据保存到硬盘

打开文件——〉读写文件——〉关闭文件

file_object=open(path,mode),path是一个字符串,代表要打开文件的路径,路径格式:"盘符:/文件夹名/.../文件夹名/文件名"

斜杠是/,在windows中,路径中的斜杠是\,

路径的两种写法:

f=open(r"E:\python文件\file.txt","r") 在路径前面加上字母r,r=raw表示是原生的字符

f=open("E:/python文件/file.txt","r")

open操作占用两方面的资源:f 是一个变量名,它的值要占用其所在应用程序的内存空间,打开文件要通过操作系统,打开的文件要占用操作系统的内存空间,

完成文件读写后,关闭文件时的步骤:

第一步:f.close() 回收操作系统资源,这一步是操作系统的事,python解释器管不到

第二步:del f,解除变量f和值之间的绑定关系,回收应用程序的内存空间,这一步python解释器的垃圾回收机制会自动帮我们做

x=int(10) #只占用其所在应用程序的内存空间

print(f)

open控制文件读写内容的模式

t 文本模式(默认的模式) :读写都是以字符串(unicode)为单位,针对文本文件的读写,需要指定encoding参数的值,

b 二进制/Bytes 模式

1. 读写都是以bytes为单位,直接将硬盘的二进制读入内存,python将其转换成了bytes类型
2. 可以用于所有文件类型
3. 不能指定字符编码,例如:图片文件,视频文件等和字符编码没关系
with open("E:/python文件/b.txt","wb") as f:
     f.write('你你好hello'.encode('gbk'))  #b模式下,不能直接写入字符串,需要先将字符串编码成二进制
     f.flush()	#告诉操作系统立马把数据写入硬盘,通常不应该这么做,通常操作系统自己会攒够了各个程序的数据,然后再写入硬盘,   

t 和b 不能单独使用,必须跟r/w/a联合使用

with open("E:/python文件/file.txt","rt") as f1:	
	res1=f1.read() #t模式会要求f1.read()读出的结果按照某种编码解码成unicode编码
    print(res1)
 #假设file.txt在硬盘上以utf-8格式的二进制存储,f1.read() 将其读入内存中还是utf-8格式的二进制,但是由于是t模式(读写都是字符串),会在内存中将utf-8格式的二进制解码成unicode编码的二进制

解码操作需要按照什么编码来解码?按照文件存入硬盘时的编码来解码

真正打开文件的是操作系统,open命令如果没有设置以什么编码方式来打开文件,操作系统就使用自己默认的编码方式来打开(解码)

如果没有指定encoding参数,操作系统会使用自己默认的编码来解码,在linux和Mac中默认utf-8,Windows中默认gbk

控制文件读写操作的模式

r 只读模式(默认模式)

r模式下的open操作

  1. 当文件不存在时,报错
  2. 当文件存在时,光标在文件的开始位置
  3. 该模式下打开文件后,不可写

res1=f1.read() #把文件的所有内容读入内存,光标移到文件末尾。如果文件很大时,会占用很多内存

#验证账号密码#
input_username=input("your name:").strip()	
input_password=input("your password:").strip()
with open("E:/python文件/user.txt","rt",encoding="utf-8") as f:
     # res=f.read()
     for line in f:
         username,password=line.strip().split(":")
         if input_username==username and input_password==password:
             print("login successfully")
             break
     else:
         print("username or password error!")

w 只写模式

该模式下的open操作

1. 当文件不存在时,创建空文件
2. 当文件存在时,清空其内容。光标在文件的开始位置
3. 该模式下打开文件后,不可读;
#文件复制#
#E:/python文件/file.txt
#E:/python文件/file_copy.txt
scr_file=input("源文件路径:").strip()
dst_file=input("目标文件路径:").strip()
with open(r'{}'.format(scr_file),"rb") as f1,\
     open(r'{}'.format(dst_file),"wb") as f2:
     #res=f1.read()	#f1数据量很大时,占用很大的内存空间,会让电脑很慢
    for line in f1:	
     	f2.write(line)

a 只追加写模式

该模式下的open操作

  1. 当文件不存在时,创建空文件
  2. 当文件存在时,光标在文件的末尾
  3. 该模式下打开文件后,不可读
  4. 该模式通常用来记录日志
#简单的注册功能——还需完善#
name=input("your name:").strip()	#还要对输入的内容的合法性进行检查
pwd=input("your password:").strip()
with open("E:/python文件/user.txt","at",encoding="utf-8") as f:
     f.write('{}:{}\n'.format(name,pwd))

文件对象的常用方法

f=open("E:/python文件/file.txt","r")
f.read()	#read方法不加参数表示从当前位置读到结尾,会读取换行符\n
f.close()
f=open("E:/python文件/file.txt","r")
f.readline()	#readline读取一行信息,保存于list,每读完一行,移到下一行开头,,会读取换行符\n
f.close()
f=open("E:/python文件/file.txt","r")
f.readlines()	#readlines从当前位置读到结尾,保存于一个字符串list中,会读取换行符\n
f.close()
#with
with open("E:/python文件/file.txt","r") as f1,\	#\表示将一行长语句写到多行去
     open("E:/python文件/file1.txt","r") as f2:
     res1=f1.read()
     res2 =f2.readline()
     print(res1)
     print(res2)

循环读取文件

#while循环#	for循环见“文件复制“代码,以行位单位读取,到达文件结尾自动结束循环
scr_file=input("源文件路径:").strip()
dst_file=input("目标文件路径:").strip()
with open(r'{}'.format(scr_file),"rb") as f1,\
     open(r'{}'.format(dst_file),"wb") as f2:
     while True:
    	res=f1.read(1024) #自己控制读取的字节数
        if len(res)==0:	#自己判断是否到达文件末尾
            break
     	f2.write(res)

如何得到bytes类型?

  1. 如果是纯英文字符串(包括数字),可以在字符串前面加b得到bytes类型
b"abc123"=="abc".encode("utf-8")	#结果为bytes类型

  1. 如果不是纯英文字符串
  2. b模式打开文件,f.read()读出的内容
bytes("上",encoding='utf-8')=="上".encode('utf-8') #结果为bytes类型

控制文件指针的移动

文件指针以字节bytes为单位移动

特殊情况:t模式下的read(n),n代表的是字符个数

f.seek(n,模式),n表示移动的字节数,模式有三种:0,1,2分别表示

模式 0 1 2
从文件开始位置移动 从指针当前位置移动 从文件末尾位置移动
(此时,n一般为负数)
在t还是b模式下使用 t模式/b模式 b模式 b模式
f.seek(9,0)
f.seek(3,0)

f.tell() #返回指针当前的位置

with open("E:/python文件/b.txt","rb") as f:
     # f.seek(9,2)
     f.seek(2,0)	#GBK编码用2个字节对应一个中文字符,如果指针的位置在一个中文字符内,会出错
     print(f.tell())
     res=f.read()
     print(res.decode('gbk'))
#动态获取文件新增内容#
with open("E:/python文件/b.txt","ab") as f:
     str=input("输入新内容:")
     num=len(str.encode('gbk'))	#编码方式根据具体情况而定	
     f.write("{}".format(str).encode('gbk'))
        
        
with open("E:/python文件/b.txt", "rb") as f:        
	 f.seek(-num,2)
     res=f.read()
     print(res.decode('gbk'))

#先运行以下程序,然后向目标文件中追加内容#
import time
with open("E:/python文件/b.txt", "rb") as f:
    f.seek(0, 2)
    while 1:
        res = f.readline()
        if len(res)==0:
            time.sleep(0.5)
        else:
            print(res.decode('gbk'))
        
     

修改文件的两种方式

方式一:也是文本编辑器使用的方式

优点:省硬盘空间,缺点:文件大时,占用内存空间

with open("c.txt",'rt',encoding='utf-8') as f:
     data=f.read()	#文件大时,一下全读入内存,占用内存空间
     res=data.replace('sb','smart')
with open("c.txt", 'wt', encoding='utf-8') as f:
     f.write(res)

方式二:优点:省内存空间,缺点:占用硬盘空间

import os
with open("c.txt",'rt',encoding='utf-8') as f,\
     open("c1.txt",'wt',encoding='utf-8') as f1:
     for line in f:
          f1.write(line.replace('smart','gentleman'))
os.remove('c.txt')	#删除源文件,
os.rename('c1.txt','c.txt')	#将新文件重命名为源文件的名称