文件处理

文件处理

  • 什么是文件?
    • 操作系统提供给用户操作硬盘的一个工具
  • 为什么要用文件?
    • 因为人类和计算机要永久保存数据
  • 怎么用文件?
f = open('a.txt', 'r', encoding='utf-8')	#默认打开模式就为r
data = f.read()	#调用文件对象下的读/写方法
print(data)

with的用法:

with open('a.txt', 'w') as f:
    pass
#可以用with同事打开多个文件,用逗号分隔
with open('a.txt', 'r') as read_f, open('b.txt', 'w') as write_f:
    data = read_f.read()
    write_f.write(data)

一、文件操作模式

如果open函数中的encoding没有设置,默认是GBK,所以一般需要添加encoding参数

  • r(默认)
    • 只读
    • 如果读的文件不存在,报错
with open('a.txt', 'r', encoding='utf-8') as f:
    res = f.read()
  • w:
    • 只写
    • 如果文件不存在,新建一个文件写入数据
    • 如果文件存在且存在数据,会清空数据,重新写入
with open('a.txt', 'w', encoding='utf-8') as f:
    f.write('hello!')
  • a:
    • 只追加写
    • 如果文件不存在,新建一个文件写入数据
    • 如果文件存在且存在数据,会在已有的数据后面追加写入数据
with open('a.txt', 'a', encoding='utf-8') as f:
    f.write('\nmy name is Yang')

二、文件读写模式


前提:tb模式不能单独使用,必须与r/w/a之一结合使用

  • t:文本模式
    • 读写文件都是以字符串为单位的
    • 只能针对文本文件
    • 必须制定encoding参数
with open('a.txt', 'rt', encoding='utf-8') as f:
    res = f.read()
    print(type(res))
    <class 'str'>
with open('a.txt', 'wt',encoding='utf-8') as f:
    s = 'abc'
    f.write(s)	#写入也必须是字符串类型
  • b:二进制模式
    • 读写文件都是以bytes/二进制位单位的
    • 可以针对所有文件
    • 一定不能指定encoding参数
with open('1.png', 'rb') as f:
    data = f.read()
    print(type(data))
    <class 'bytes'>
with open("a.txt", "wb") as f:
    msg = 'hello'
    res = msg.encode('utf-8')	#res为bytes类型
    f.write(res)	#在b模式下写入文件的只能是bytes类型

三、操作文件的方法


  • 读操作
f.read()		#读取所有内容,执行完后,文件指针会移动到文件末尾
f.readline()	#读取一行内容,光标移到到第二行首部
f.readlines()	#读取每一行内容,存放于列表中
  • 写操作
f.write('1111\n2222\n')	#针对文本模式的写,需要自己写换行符
f.write('1111\n2222\n'.encode('utf-8'))	#针对b模式的写,需要自己写换行符
f.writelines(['333/n', '444\n'])	#文件模式
f.writelines([bytes('333\n', encoding='utf-8'), '444\n'.encode('utf-8')])#b模式
f.readable()		# 文件是否可读
f.writable()		# 文件是否可写
f.closed			# 文件是否关闭
f.encoding			# 如果文件打开模式为b,则没有该属性
f.flush()			#立刻将文件内容刷到硬盘
f.name

四、主动控制文件内指针移动

除了read里的参数,read(n),是针对字符的,其他的都是针对字节(Bytes)

with open('a.txt', 'r', encoding='utf-8') as f:
    res = f.read(3)		#读取3个字符

with open('a.txt', 'rb',)as f:
    res = f.read(3)		#读取3个bytes
  • 若想要读取文件某一特定位置的数据,则需要f.seek方法主动控制文件内指针的移动:

  • f.seek(offset,whence)

    • offset:相对偏移度(光标移动的位数)针对字节
    • whence:指定光标位置从何开始
      • 0:默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
      • 1:该模式代表指针移动的字节数是以当前所在的位置为参照的
      • 2:该模式代表指针移动的字节数是以文件末尾的位置为参照的
  • 0模式

with open('a.txt', 'r', encoding='utf8') as f:
    f.seek(3, 0)		#参照文件开头移动了3个字节
    print(f.tell())		#查看当前文件指针距离文件开头的距离
    print(f.read())		#从指针的后面读取到文件末尾
  • 1模式
with open('a.txt', 'rb')as f:
    f.seek(3, 1)		#从当前位置往后移3个字节
    print(f.tell())
    f.seek(4, 1)		#从移动了3个字节后的当前位置往后再移动4个字节
    print(f.tell())		#所以这里的结果是 7
  • 2模式
with open('a.txt', 'rb',)as f:
    f.seek(0, 2)		#参照文件末尾移动0个字节,即直接跳到文件末尾
    print(f.tell())
    f.seek(-3, 2)		#参照文件末尾往前移动了3个字节
    print(f.read().decode('utf8'))

五、文件的修改

方法一:将文件内容一次性全部读入内存,然后在内存中修改完毕后,再覆盖写回原文件

优先:在文件修改过程中同一份数据只有一份

缺点:会过多地占用内存

with open('a.txt', 'r', encoding='utf8')as f:
    res = f.read()

with open('a.txt', 'w', encoding='utf8')as f:
    data = f.write(res.replace('SB', 'this is a new inmanage'))
    print(data)

方法二:以读的方式打开源文件,以写的方式打开一个临时文件,一行行读取源文件内容,修改完后写入临时文件,删掉源文件,将临时文件重命名为源文件名

优点:不会占用过多内存

缺点:在文件修改过程中同一份数据存了两份

import os

with open('a.txt', 'r', encoding='utf8')as read_f,\
        open('b.txt', 'w', encoding='utf8')as write_f:
    for line in read_f:
        write_f.write(line.replace('yes, ok ok', 'are you ok'))

os.remove('a.txt')
os.rename('b.txt', 'a.txt')
posted @ 2019-11-08 19:08  YGZICO  阅读(120)  评论(0编辑  收藏  举报