文件处理

一、文件操作流程

  什么是文件?

  文件是操作系统提供给应用程序来操作硬盘的一个工具,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作

  为什么要用文件?

  需要永久保存数据

  基本流程

    1、打开文件,由应用程序向操作系统发起系统调用open(),操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给变量f

    f = open('文件路径','打开文件的模式','编码')

      # 文件路径可以是相对路径,也可以是绝对路径

      # 默认打开方式就是r

      # 指定打开字符编码,什么方式存,就以什么方式打开

    2、调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘操作

    data = f.read()

    3、向操作系统发起关闭文件的请求,回收资源

    f.close()

    在操作完一个文件后,必须把与该文件有关的资源全部回收,变量资源python可以自动回收,但是操作系统打开的文件资源不能自动关闭,这就需要close()方法来关闭,还有另外一种方式打开文件,会自动执行close():

# 打开一个文件
with open('a.txt','r',encoding='utf-8')as f:
    pass

# 可以同时打开多个文件
with open('a.txt','r',encoding='utf-8')as rf, \
            open('a.txt','w',encoding='utf-8')as wf:
    print(rf.read())
    wf.write('123')

二、文件操作模式

  1、文件打开模式     

    r:只读:
      1、只能读,不能写
      2、如果文件不存在的话,就会报错

# 判断文件是否可读
with open('test.txt', 'r', encoding='utf-8')as f:
    print(f.readable())

# 读取文件全部内容
with open('test.txt', 'r', encoding='utf-8')as f:
    data = f.read()
    print(data)

# 循环读取文件中每行的内容
with open('test.txt', 'r', encoding='utf-8')as f:
    for line in f:
        print(line)

# readline() 每次读取一行内容
with open('test.txt', 'r', encoding='utf-8')as f:
    print(f.readline())
    print(f.readline())
    print(f.readline())
    print(f.readline())

# readlines() 将数据全部读入内存,以换行符分隔,存入列表
with open('test.txt', 'r', encoding='utf-8')as f:
    line = f.readlines()
    print(line)

    w:只写:
      1、只能写,不能读
      2、如果文件不存在的话,会创建新文件
      3、如果文件存在的话,先清空源文件,再写入新文件

with open('test.txt', 'w', encoding='utf-8')as f:
    print(f.writable())
    f.write('123')
    f.write('111')
    f.write('123')

    a:追加写:
      1、只能写,不能读
      2、如果文件不存在的话,会创建新文件
      3、如果文件存在的话,会在原数据的末尾追加新数据

with open('test.txt', 'a', encoding='utf-8')as f:
    f.write('aaa')

    r+、w+、a+:可读可写

  2、文件处理模式

    t 模式:如果我们指定文件打开模式为r/w/a,其实默认就是rt/wt/at

      t 模式只能用于操作文本文件,无论读写,都应以字符串为单位

    b 模式:读写都是以二进制

with open('test.txt', 'rb')as f:
    res = f.read()
    print(type(res))    # 输出结果为:<class 'bytes'>

with open('test.txt', 'wb')as f:
    msg = '你好'
    res = msg.encode('utf-8')   # res为bytes类型
    f.write(res)                # 在b模式下写入文件的只能是bytes类型

    在操作纯文本文件方面t模式帮我们省去了编码与解码的过程,b模式则需要手动编码与解码,所以此时t更方便

    针对非文本文件(如图片、音频、视频)只能使用b模式

三、文件内光标移动

    文件内指针的移动都是bytes为单位的,唯一例外的是t模式下的read(n),n是以字符为单位的

with open('test.txt', 'r')as f:
    data = f.read(3)    # 读取3个字符
    
with open('test.txt', 'rb')as f:
    data = f.read(3)    # 读取3个bytes

  seek方法:

    seek有两个参数:seek(offset,whence)

      offset:相对偏移度 (光标移动的位数)针对的是字节

      whence:指定光标位置从何开始       

        0:从文件开头
        1:从当前位置
        2:从文件末尾

      其中o模式可以在t或者b模式下使用,而1和2模式只能在b模式下用

    补充:utf-8:英文是1个bytes,中文是三个bytes

       gbk:全部是2个bytes

    o模式

with open(r"test.txt", 'r')as f:  # 打开文件的编码:gbk
    print(f.read(6))
    print(f.tell())
    f.seek(8, 0)
    print(f.read(2))
    print(f.read(5))

with open(r"test.txt", 'rt', encoding='utf-8')as f:  # 打开文件的编码:gbk
    print(f.read())
    f.seek(6, 0)
    print(f.tell())
    print(f.read(2))

    1模式

with open(r'test.txt', 'rb')as f:
    print(f.read(10).decode('gbk'))
    f.seek(10, 1)
    print(f.tell())

    2模式

with open(r'test.txt', 'rb')as f:
    f.read()
    print(f.tell())
    f.seek(-3, 2)
    print(f.tell())

四、文件的修改

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

# 将文件中的“这个”替换成“你好”
with open(r'test.txt', 'r', encoding='gbk')as f:
    data = f.read()
    print(data)
with open(r'test.txt', 'w', encoding='gbk')as f:
    res = data.replace('这个', '你好')
    f.write(res)

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

  缺点:会过多地占用内存

  2、以读的方式打开原文件,以写的方式打开另外一个临时文件,一行行读取原文件内容,修改后写入临时文件,删除原文件,将临时文件重命名原文件名

import os
with open(r'test.txt', 'r', encoding='utf-8')as rf,\
        open(r'test_wap.txt', 'w', encoding='utf-8')as wf:
    for line in rf:
        wf.write(line.replace('这个', '你好'))
os.remove('test.txt')
os.rename('test_wap.txt', 'test.txt')

  优点:不会占用过多地内存

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

posted @ 2019-11-08 19:21  treeter  阅读(270)  评论(0编辑  收藏  举报