文件操作详解(自动化运维-3)
一、文件操作流程
- 打开文件,得到文件句柄并赋值给一个变量
- 通过句柄对文件进行操作
- 关闭文件
二、测试用文件
我是一个兵, 来自老百姓, 打败了日本够强盗, 消灭了蒋匪军。 Today is a nice day, and it is weekends, so we are happy.
三、文件操作
打开文件的模式有:
- r,只读模式(默认)。
- w,只写模式。【不可读;不存在则创建;存在则删除内容;】
- a,追加模式。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+,可读写文件。【可读;可写;可追加】追加时,应该先读文件,然后写入,否则,会覆盖源文件,因为文件指针在0.
- w+,写读(可读,创建新文件,覆盖同名旧文件)
- a+,同a # 此追加直接追加到文件末尾
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
- rU
- r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
- rb
- wb
- ab
1. r , r+,rb 操作详解
# r 操作,只可以读文件,不可以写入文件, 文件读到哪里,文件指针就指到哪里
f = open("practise","r",encoding="utf-8")
print(f.read())
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
我是一个兵,
来自老百姓,
打败了日本够强盗,
消灭了蒋匪军。
Today is a nice day,
and it is weekends,
so we are happy.
151
# r+ 操作 可读可写,写操作时,从文件指针位置,向后覆盖操作。建议追加文件先读入文件到末尾,然后写入
f = open("practise","r+",encoding="utf-8")
print(f.tell())
f.write("测试一下")
print(f.tell()) # 文件指针移动到写入覆盖的位置
print(f.read())
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
0
12  #UTF-8格式,每个汉字存储在硬盘时占用三个字节,所以文件指针为 12
兵,
来自老百姓,
打败了日本够强盗,
消灭了蒋匪军。
Today is a nice day,
and it is weekends,
so we are happy.
151
# rb  #以二进制的形式读取文件,因为只是显示二进制,所以不用指定编码
f = open("practise","rb")
print(f.read())
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
b'\xe6\xb5\x8b\xe8\xaf\x95\xe4\xb8\x80\xe4\xb8\x8b\xe5\x85\xb5\xef\xbc\x8c\r\n\xe6\x9d\xa5\xe8\x87\xaa\xe8\x80\x81\xe7\x99\xbe\xe5\xa7\x93\xef\xbc\x8c\r\n\xe6\x89\x93\xe8\xb4\xa5\xe4\xba\x86\xe6\x97\xa5\xe6\x9c\xac\xe5\xa4\x9f\xe5\xbc\xba\xe7\x9b\x97\xef\xbc\x8c\r\n\xe6\xb6\x88\xe7\x81\xad\xe4\xba\x86\xe8\x92\x8b\xe5\x8c\xaa\xe5\x86\x9b\xe3\x80\x82\r\nToday is a nice day,\r\nand it is weekends,\r\nso we are happy.'
151
2. w, w+, wb 操作详解
# w 操作,只写模式,如果文件不存在,则创建新的文件,如果文件存在则覆盖旧的文件,并清空旧的文件的内容
f = open("practise","w",encoding="utf-8")
f.write("只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
21
# w+ 操作,可读可写,如果要从文件开始读,需要把文件指针调整到 0
f = open("practise","w+",encoding="utf-8")
f.write("只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
print(f.read())  # 因为文件指针在文件末尾,所以什么也读不到
print(f.seek(0)) # 调整文件指针到文件开头
print(f.read()) # 读取整个文件内容
#执行结果
21
0
只可写,不可读
# wb 操作,以二进制的形式写入文件,因为写二进制所以不需要指定编码,但是写入的字符串必须是 bytes 类型
f = open("practise","wb")
f.write("只可写,不可读".encode('utf-8'))
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
21
3. a, a+,ab 操作详解
# a 操作, 追加文件,不存在则创建文件,存在则追加内容到文件末尾。不可读. 移动指针位置没有任何效果,可以自行测试
f = open("practise","a",encoding="utf-8")
f.write("只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.write("\n只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.write("\n只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
21
44
67
# a+ 操作, 追加文件,不存在则创建文件,存在则追加内容到文件末尾,可读,读取文件需要移动文件指针到开头。
f = open("practise","a+",encoding="utf-8")
f.write("只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.seek(0)
f.write("\n只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.write("\n只可写,不可读")
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.seek(0) # 必须移动文件指针到开头,否则从文件末尾读取,什么也读取不到
print(f.read())
#执行结果
21
44
67
只可写,不可读
只可写,不可读
只可写,不可读
# ab 操作,以二进制的形式追加,不需要指定字符集
f = open("practise","ab")
f.write("只可写,不可读".encode("utf-8"))
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.seek(0)
f.write("\n只可写,不可读".encode("utf-8"))
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
f.write("\n只可写,不可读".encode("utf-8"))
print(f.tell()) # 查看文件指针的位置,以文件在硬盘存储的字节数计算
#执行结果
21
22
44
四、文件对象属性方法详解 ,使用上面的测试文件测试
f = open("practise","r",encoding="utf-8")
print(f.read()) #读取整个文件的内容
print(f.closed) # 查看文件是否关闭
print(f.encoding) # 查看文件编码
print(f.tell()) # 打印文件指针的位置
print(f.seek(0)) # 重设文件指针的位置
print(f.errors)  # 做异常处理用的
print(f.fileno()) # 返回文件句柄在内存中的编号
print(f.name) # 打印文件名
print(f.isatty()) # 查看是否是终端设备文件
print(f.seekable()) # 判断文件指针是否可移动
print(f.writable()) # 判断文件是否可写
print(f.readable()) # 判断文件是否可读
f.flush() # 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
f.truncate() #从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后 V 后面的所有字符被删除,其中 Widnows 系统下的换行代表2个字符大小。 必须具有写权限
print(f.readline()) # 从文件指针位置读取一行
print(f.readlines()) # 从文件指针处读取所有文件,并转换为列表的形式
file.writelines() # 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。需要文件有写权限
五、循环读取文件的两种方式
f = open("practise","r",encoding="utf-8")
for i in f.readlines():  #此方法用于循环读取小文件。如果文件有两个G,那转成列表恐怕就悲剧了
    print(i.strip()) #strip() 去除字符串两边的空格和换行等字符
print("test".center(80,"#"))
f.seek(0) #移动指针到位置0,否则取不到文件
for i in f:   # 推荐使用此方法,f 是迭代器,不过多占用内存空间
    print(i.strip())
f.close() #关闭文件,关闭后文件不能再进行读写操作
#执行结果
我是一个兵,
来自老百姓,
打败了日本够强盗,
消灭了蒋匪军。
Today is a nice day,
and it is weekends,
so we are happy.
######################################test######################################
我是一个兵,
来自老百姓,
打败了日本够强盗,
消灭了蒋匪军。
Today is a nice day,
and it is weekends,
so we are happy.
六、如何修改文件
两种方式:
- 文件读取到内存,编辑后,重新写入源文件,类似于 vim,(在内存中修改)
- 边读边修改文件,写入内容到新的文件 (直接写入到新的文件)
首先介绍一下打开文件句柄,防止程序中忘记关闭文件
with open("practise","r",encoding="utf-8") as f:
    print(f.read())
修改文件方式 1
new = ""  # 初始化一个空字符串
with open("practise","r",encoding="utf-8") as f:
    for i in f:
        if "我是一个兵" in i:
            i = i.replace("我是一个兵","我是好学生")
        new += i
with open("practise","w",encoding="utf-8") as f:
    f.write(new)
修改文件方式 2
with open("practise","r",encoding="utf-8") as f,open("practise2","w",encoding="utf-8") as f1:
    for i in f:
        if "我是一个兵" in i:
            i = i.replace("我是一个兵","我是好学生")
        f1.write(i)
七、小案例
依次打印26个英文字母
import sys,time
for i in range(65,91):
    sys.stdout.write(chr(i)+" ")
    sys.stdout.flush()
    time.sleep(0.5)
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号