文件操作详解(自动化运维-3)

一、文件操作流程

  1. 打开文件,得到文件句柄并赋值给一个变量
  2. 通过句柄对文件进行操作
  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.

 六、如何修改文件

两种方式:

  1. 文件读取到内存,编辑后,重新写入源文件,类似于 vim,(在内存中修改)
  2. 边读边修改文件,写入内容到新的文件 (直接写入到新的文件)

首先介绍一下打开文件句柄,防止程序中忘记关闭文件

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)

 

posted @ 2018-03-23 16:47  步绍训  阅读(202)  评论(0)    收藏  举报