Python的文件操作

一、什么是文件
文件定义:文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口
用户/应用程序(open())
操作系统(文件)
计算机硬件(硬盘)
二、为何要用文件(文件作用)
用户/应用程序可以通过文件将数据永久保存的硬盘中,即操作文件就是操作硬盘
用户/应用程序直接操作的是文件,对文件进行的所有的操作,都是在向操作系统发送系统调用,然后再由操作将其转换成具体的硬盘操作。
三、如何用文件:open()
# 1、打开文件
# windows路径分隔符问题
# open('C:\a.txt\nb\c\d.txt')
# # 解决方案一:推荐
# open(r'C:\a.txt\nb\c\d.txt')
# # 注意:\在python解释器中也有转义的意思
# # 解决方案二:
# open('C:/a.txt/nb/c/d.txt')

# f=open(r'a.txt',mode='rt') # f的值是一种变量,占用的是应用程序的内存空间
# print(f)  # <_io.TextIOWrapper name='a.txt' mode='rt' encoding='cp936'>

# x=int(10)  # x也是一个种变量,占用的是也是应用程序的内存空间
# print(x)  # 10

#
2、操作文件:读/写文件,应用程序对文件的读写请求都是在向操作系统发送 # 系统调用,然后由操作系统控制硬盘把输入读入内存、或者写入硬盘 res=f.read() print(type(res)) # <class 'str'> print(res) """ # coding:utf-8 aaa 鍝堝搱 """
# 3、关闭文件
# 当打开一个文件包含两部分资源:应用程序的变量f和操作系统打开的文件。
  在操作完毕一个文件时,必须把与该文件的这两部分资源全部回收,回收方法为:
# f.close() # 回收操作系统资源 # print(f) # f.read() # 变量f存在,但是不能再读了 # del f # 回收应用程序资源
# 其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件无法关闭,占用资源, 而python自动的垃圾回收机制决定了我们无需考虑
# del f,
这就要求在操作完毕文件后,一定要记住f.close(),为了避免忘记关闭文件的事情发生 python提供了with关键字来帮我们管理上下文。 # 文件对象又称为文件句柄 # with open('a.txt',mode='rt') as f1: # f1=open('a.txt',mode='rt') # res=f1.read() # print(res) # 使用\符号进行折行 with open('a.txt',mode='rt') as f1,\ open('b.txt',mode='rt') as f2: res1=f1.read() res2=f2.read() print(res1) print(res2) # 当with语句执行完毕时也就相当于执行了下面的两行代码 # f1.close() # f2.close()
       
四、控制文件读写内容的模式:t和b
   强调:t和b不能单独使用,必须跟r/w/a连用
t文本(默认的模式)
1、读写都以str(unicode)为单位的
2、文本文件
3、必须指定encoding='utf-8'
     x模式:
       x, 只写模式【不可读;不存在则创建,存在则报错】


     b:binary模式(b二进制/bytes)
        1、读写都是以bytes为单位
    2、可以针对所有文件
    3、一定不能指定字符编码,即一定不能指定encoding参数
  总结:
    1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
    2、针对非文本文件(如图片、视频、音频等)只能使用b模式

4.1、控制文件读写内容的t模式:
# 没有指定encoding参数操作系统会使用自己默认的编码
# linux系统默认utf-8
# windows系统默认gbk
with open('c.txt',mode='rt',encoding='utf-8') as f:
    res=f.read() # t模式会将f.read()读出的结果解码成unicode
    print(res,type(res))

# 内存:utf-8格式的二进制-----解码-----》unicode
# 硬盘(c.txt内容:utf-8格式的二进制)
        控制文件读写操作的模式
r只读模式
w只写模式
a只追加写模式
+:r+、w+、a+
# # 1、r(默认的操作模式):只读模式,当文件不存在时报错,当文件存在时文件指针跳到开始位置
# with open('c.txt',mode='rt',encoding='utf-8') as f:
#     print('第一次读'.center(50,'*'))
#     res=f.read() # 把所有内容从硬盘读入内存
#     print(res)
#
# # with open('c.txt', mode='rt', encoding='utf-8') as f:
#     print('第二次读'.center(50,'*'))
#     res1=f.read()
#     print(res1)
"""
***********************第一次读***********************
哈哈哈哈
***********************第二次读***********************
"""
# ===============案例==================
inp_username=input('your name>>: ').strip()
inp_password=input('your password>>: ').strip()
# 验证只读模式。
# with open('user.txt',mode='rt',encoding='utf-8') as f:
with open(r'user.txt',mode='rt',encoding='utf-8') as f: # 与上面效果相同
    for line in f:
        # print(line,end='') # egon:123\n
        username,password=line.strip().split(':')
# username, password = line.strip("\n").split(":") # 与上面的效果一样
        if inp_username == username and inp_password == password:
            print('login successfull')
            break
    else:
        print('账号或密码错误')
# 2、w:只写模式,当文件不存在时会创建空文件,当文件存在会清空文件,指针位于开始位置
# with open('d.txt',mode='wt',encoding='utf-8') as f:
    # f.read() # 只写模式下调用读的功能后报错,提示io不可读 io.UnsupportedOperation: not readable
    # f.write('人生苦短,我爱python\n')
# 查看写入情况
# with open('d.txt',mode='rt',encoding='utf-8') as f:
#     res = f.read()
#     print(f)  # <_io.TextIOWrapper name='d.txt' mode='rt' encoding='utf-8'>
#     print(res)  # 人生苦短,我爱python

# 强调1:
# 在以w模式打开文件没有关闭的情况下,连续写入,新的内容总是跟在旧的之后
# with open('d.txt',mode='wt',encoding='utf-8') as f:
#     f.write('人生苦短,我爱python1\n')
#     f.write('人生苦短,我爱python2\n')
#     f.write('人生苦短,我爱python3\n')

# 强调2:
# 如果重新以w模式打开文件,则会清空文件内容
# with open('d.txt',mode='wt',encoding='utf-8') as f:
#     f.write('人生苦短,我爱python1\n')
# with open('d.txt',mode='wt',encoding='utf-8') as f:
#     f.write('人生苦短,我爱python2\n')
# with open('d.txt',mode='wt',encoding='utf-8') as f:
#     f.write('人生苦短,我爱python3\n')

# 案例:w模式用来创建全新的文件
# 文件文件的copy工具
# src_file=input('源文件路径>>: ').strip()  # 源文件路径>>: D:\pycharm\oldboy_29\0313\user.txt
# dst_file=input('目标文件路径>>: ').strip() # 目标文件路径>>: D:\pycharm\oldboy_29\0313\user1.txt
# # 复制文件内容
# with open(r'{}'.format(src_file),mode='rt',encoding='utf-8') as f1,\
#     open(r'{}'.format(dst_file),mode='wt',encoding='utf-8') as f2:
#     res=f1.read()
#     f2.write(res)
# print(res)
# 3、a:只追加写,在文件不存在时会创建空文档,在文件存在时文件指针会直接调到末尾
# with open('e.txt',mode='at',encoding='utf-8') as f:
#     # f.read() # 报错,不能读
#     f.write('人生苦短,我爱python1\n')
#     f.write('人生苦短,我爱python2\n')
#     f.write('人生苦短,我爱python3\n')

# 强调 w 模式与 a 模式的异同:
# 1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
# 2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后

# 案例:a模式用来在原有的文件内存的基础之上写入新的内容,比如记录日志、注册
# 注册功能
# name=input('your name>>: ')
# pwd=input('your name>>: ')
# with open('db.txt',mode='at',encoding='utf-8') as f:
#     f.write('{}:{}\n'.format(name,pwd))
# your name>>: lsj
# your name>>: 123
# 了解:+不能单独使用,必须配合r、w、a
# r+操作
# with open('g.txt',mode='rt+',encoding='utf-8') as f:
#     # print(f.read())
#     f.write('中国')
# w+操作
# with open('g.txt',mode='w+t',encoding='utf-8') as f:
#     f.write('111\n')
#     f.write('222\n')
#     f.write('333\n')
#     print('====>',f.read())

# a+操作
# with open('g.txt',mode='a+t',encoding='utf-8') as f:
#     print(f.read())
#     f.write('444\n')
#     f.write('5555\n')
#     print(f.read())

4.2、控制文件读写内容的x模式:

    x模式(控制文件操作的模式)-》了解

      x, 只写模式【不可读;不存在则创建,存在则报错】

with open(r"a.txt",mode="x",encoding="utf-8") as f:
    f.write("注意write使用'\n'的使用\n")

4.3、控制文件读写内容的b模式:

b:binary模式
1、读写都是以bytes(二进制)为单位
2、可以针对所有文件
3、一定不能指定字符编码,即一定不能指定encoding参数

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

    针对非文本文件(如图片、视频、音频等)只能使用b模式
# 错误演示:t模式只能读文本文件,下面让t模式读MP4格式的文件
# with open(r'爱nmlgb的爱情.mp4',mode='rt') as f:
#     f.read() # 硬盘的二进制读入内存-》t模式会将读入内存的内容进行decode解码操作
# 因为Windows系统默认的解码格式为gbk,所以报错如下错误
# UnicodeDecodeError: 'gbk' codec can't decode byte 0xc0 in position 59: illegal multibyte sequence

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

with open(r'test.jpg',mode='rb',encoding='utf-8') as f:
    res=f.read() # 硬盘的二进制读入内存—>b模式下,不做任何转换,直接读入内存
    print(res) # bytes类型—》当成二进制
    print(type(res))
# 指定二进制模式的编码参数时会报错
# ValueError: binary mode doesn't take an encoding argument

 

 d.txt文件中写入“哈哈哈a”,保存格式为utf-8,那么在读取该文件时也要用“utf-8”进行解码

with open(r'd.txt',mode='rb') as f:
    res=f.read() # utf-8的二进制
    print(res,type(res)) # b'\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88a' <class 'bytes'>
    # 要想看到结果使用decode()方法进行解码
    print(res.decode('utf-8'))  # 哈哈哈a(utf-8中一个中文字符是3Bytes,一个英文字符是1Bytes)
    print(res.decode('gbk'))  # 如果使用‘gbk’解码,会出现乱码:鍝堝搱鍝坅
# (utf-8中一个中文字符是3Bytes,一个英文字符是1Bytes)
# b'
# \xe5\x93\x88  -->哈
# \xe5\x93\x88  -->哈
# \xe5\x93\x88  -->哈
# a             -->a
# '
# 上面代码可以这样写
with open(r'd.txt',mode='rt',encoding='utf-8') as f:
    res=f.read() # utf-8的二进制->unicode
    print(res)
# 写入的时候用的什么格式编码,读取时候就要用什么格式解码,否则出现乱码。
with open(r'f.txt',mode='wb') as f:
    # f.write('你好hello'.encode('utf-8'))  # 使用utf-8格式编码将内容写入文件
    f.write('哈哈哈'.encode('gbk')) # 使用gbk格式编码将内容写入文件

with open(r"f.txt",mode="rb") as f:
   res = f.read()
   # print(res.decode("utf-8")) # 使用utf-8格式解码读取文件内容
   print(res.decode("gbk")) # 使用gbk格式解码读取文件内容
# 通用文件copy工具实现
src_file = input("请输入源文件路径:").strip()
des_file = input("请输入目标文件路径:").strip()
with open(r"{}".format(src_file),mode="rb") as f1,\
        open(r"{}".format(des_file),mode='wb') as f2:
    for line in f1: # 建议使用for循环
        f2.write(line)

    res = f1.read() # 因为当文件数据量过多时,可能会占用大量空间,所以不建议使用
    f2.write(res)

、操作文件的其他方法:

5.1、 读操作
f.read()  # 读取所有内容,执行完该操作后,文件指针会移动到文件末尾
f.readline()  # 读取一行内容,光标移动到第二行首部
f.readlines()  # 读取每一行内容,存放于列表中

前提:定义一个g.txt 文件里的内容如下:
111
222
333
444
5555
# 一:读相关操作
# 1、readline:一次只能读一行
with open(r'g.txt',mode='rt',encoding='utf-8') as f:
    # res1=f.readline()
    # print(res1)  # 读取出文件的第一行:111
    # res2=f.readline()
    # print(res2) # 读取出文件的第二行:222

    # 使用循环读取出文件的所有行
    while True:
        line=f.readline()
        if len(line) == 0:
            break
        print(line)
"""
111

222

333

444

5555
"""
# 2、readlines:读取每一行内容,存放于列表中
with open(r'g.txt',mode='rt',encoding='utf-8') as f:
    res=f.readlines()
    print(res)  # ['111\n', '222\n', '333\n', '444\n', '5555']
# 强调:
# f.read()与f.readlines()都是将内容一次性读入内存,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读入,有两种实现方式:
# 循环读取文件:方式一
with open('g.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        print(line) # 同一时刻只读入一行内容到内存中
#以行为单位读,当一行内容过长时会导致一次性读入内容的数据量过大
# with open(r'g.txt',mode='rt',encoding='utf-8') as f:
#     for line in f:
#         print(len(line),line)
# """
# 4 111
#
# 4 222
#
# 4 333
#
# 4 444
#
# 4 5555
# """
# with open(r'g.txt',mode='rb') as f:
#     for line in f:
#         print(line)
"""
b'111\n'
b'222\n'
b'333\n'
b'444\n'
b'5555'
"""
# with open(r'test.jpg',mode='rb') as f:
#     for line in f:
#         print(line)
"""
b'\xff\xd8\xff\xdb\x00C\x00\x0b\t\n'
b'\x0b\n'
b'\x11\r\x0b\x15\x0b\x0e\x0e\r\x0f\x13 \x15\x13\x12\x12\x13\'\x1c\x1e\x17 .)10.)-,3:J>36F7,
-@WAFLNRSR2>ZaZP`JQRO\xff\xdb\x00C\x01\x0c\x0e\x0e\x13#\'&\x15\x15&O5
-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO\xff\xc0\x00\x11\x08\x01\xc8\x01\xdc\x03\x01"\x00\x02\x11\x01
"""
 # 方式二 
with open('1.mp4',mode='rb') as f:
  
while True:
    data
=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
    if len(data) == 0:
      
break
      print(data)
# 循环读取文件
# 方式一:自己控制每次读取的数据的数据量
with open(r'test.jpg',mode='rb') as f:
    while True:
        res=f.read(1024) # 按照字节取值,可以控制字符量1024
        if len(res) == 0:
            break
        print(len(res))
"""
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
412
"""
 

六、写的相关操作

# 写相关操作
# f.writelines():
with open('h.txt',mode='wt',encoding='utf-8') as f:
    # f.write('1111\n222\n3333\n')  # 针对文本模式的写,需要自己写换行符

    # l=['11111\n','2222','3333',4444]  # write()参数必须是str,而不是int类型。TypeError: write() argument must be str, not int
    # l=['11111\n','2222','3333']
    # f.writelines(l)
    """上面的结果如下,需要自己写换行符
    11111
    22223333
    """
    # l=['11111\n','2222','3333']
    # for line in l:
    #     f.write(line)
    """使用for循环实现 与f.writelines(l)效果同
    11111
    22223333
    """
with open('h.txt', mode='wb') as f:
    l = [
        '1111aaa1\n'.encode('utf-8'),
        '222bb2'.encode('utf-8'),
        '33eee33'.encode('utf-8')
    ]
    f.writelines(l)
"""
1111aaa1
222bb233eee33
"""
# with open('h.txt', mode='wb') as f:
# # 补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型
# l = [
# b'1111aaa1\n',
# b'222bb2',
# b'33eee33'
# ]
# f.writelines(l)
"""
1111aaa1
222bb233eee33
"""
# with open('h.txt', mode='wb') as f:
# # 补充2:'上'.encode('utf-8') 等同于bytes('上',encoding='utf-8')
# l = [
# bytes('上啊',encoding='utf-8'),
# bytes('冲呀',encoding='utf-8'),
# bytes('弟兄们',encoding='utf-8'),
# ]
# f.writelines(l)
# """
# 上啊冲呀弟兄们
# """
# flush:立刻将文件内容从内存刷到硬盘
# with open('h.txt', mode='wt',encoding='utf-8') as f:
    # f.write('哈')  # h.txt文件中写入“哈”
    # f.flush()
# 了解
# with open('h.txt', mode='wt',encoding='utf-8') as f:
    # print(f.readable()) # 文件是否可读  False
    # print(f.writable())  # 文件是否可读  True
    # print(f.encoding)  # 如果文件打开模式为b,则没有该属性,查看文件属性
    # print(f.name)  # 输出文件名 h.txt
    # print(f.closed)  # 文件是否关闭   False

 

七、指针;来源于C语言(笔尖)

#大前提:文件内指针的移动都是Bytes(字节)为单位的,唯一例外的是t模式下的read(n),n以字符为单位
with open('a.txt',mode='rt',encoding='utf-8') as f:
     data=f.read(3) # 读取3个字符

with open('a.txt',mode='rb') as f:
     data=f.read(3) # 读取3个Bytes
# 7.1、t模式下的read(n),n代表的是字符个数   utf-8中一个中文字符=3个字节(3Bytes)  一个英文字符= 1字节1bytes
with open('aaa.txt',mode='rt',encoding='utf-8') as f:
    # res3=f.read(3) # 读取3个字符
    # res4=f.read(4) # 读取4个字符
    res5=f.read(5)  # 读取5个字符
    # print(res3)  # abc
    # print(res4)  # abc你
    print(res5)  # abc你好
# 7.2、对比一下b模式下 read(n),n代表字节数,data=f.read(3) # 读取3个Bytes
with open('aaa.txt',mode='rb') as f:
    # res3=f.read(3)  # 读取3个Bytes
    # res4=f.read(4)  # 读取4个Bytes
    # res5=f.read(5)  # 读取5个Bytes
    res6=f.read(6)  # 读取6个Bytes
    # print(res3)  # b'abc'
    # print(res4)  # b'abc\xe4'
    # print(res5)  # b'abc\xe4\xbd'
    # print(res6)  # b'abc\xe4\xbd\xa0' abc你 与t模式下res4=f.read(4) 效果同
   print(res6.decode('utf-8')) # 手动改写解码格式得到 
# 之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则则需要用f.seek方法主动控制文件内指针的移动,
  详细用法如下:
# f.seek(指针移动的字节数,模式控制): # 模式控制: # 0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的 # 1: 该模式代表指针移动的字节数是以当前所在的位置为参照的 # 2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的 # 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用

 

# a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
# abc你好  # res = f.read()  # b'abc\xe4\xbd\xa0\xe5\xa5\xbd'
with open('aaa.txt',mode='rb') as f:
    res = f.read()  # b'abc\xe4\xbd\xa0\xe5\xa5\xbd'
    print(res)  #

7.3、f.seek(指针移动的字节数,模式控制)
# 模式0:参照物是文件开头位置
# with open('aaa.txt',mode='rb') as f:
#     # res = f.seek(9,0)  # 9
#     # res = f.seek(3,0)  # 3
#     print(res)  #

# 模式1:参照物是当前指针所在位置
# with open('aaa.txt',mode='rb') as f:
    # res = f.seek(9,1) # 9
    # res = f.seek(3,1) # 12
    # print(res)

# 模式2:参照物是文件末尾位置,应该倒着移动
with open('aaa.txt', mode='rb') as f:
    res = f.seek(-9,2) # 0
    # res = f.seek(-3,2) # 6
    print(res)

# 强调:只有0模式可以在t下使用,1、2必须在b模式下用
# f.tell() # 获取文件指针当前位置

# 示范
with open('aaa.txt',mode='rb') as f:
    f.seek(3,0) # 3
    res = f.seek(3,0) # 3
    # 以下两种效果相同
    print(f.tell())
    print(res)
with open('aaa.txt',mode='rt',encoding='utf-8') as f:
    f.seek(3,0)     # 参照文件开头移动了3个字节
    print(f.tell()) # 查看当前文件指针距离文件开头的位置,输出结果为3
    print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
    # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败
解码失败实例
with open('aaa.txt',mode='rb') as f:
f.seek(4,0)
res=f.read()
print(res) # b'\xbd\xa0\xe5\xa5\xbd'
print(res.decode('utf-8')) # 由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败
# UnicodeDecodeError: 'utf-8' codec无法解码字节0xbd在位置0:无效的开始字节
with open('aaa.txt',mode='rb') as f:
    f.seek(9,1)
    f.seek(3,1) # 12
    print(f.tell())

with open('aaa.txt',mode='rb') as f:
    # f.seek(-9,2)  
    # print(f.tell())  # 0
    # print(f.read().decode('utf-8'))  # abc你好
    # f.seek(-3,2)
    # print(f.tell())  # 6
    print(f.read().decode('utf-8'))  #

 

# 小练习:实现动态查看最新一条日志的效果
# 1、写个日志进行追加
with open('access.log',mode="at",encoding="utf-8") as w:
    w.write("2020年3月17日  文件日志 \n")

# 2.查看最新一条日志
import time
with open("access.log",mode="rb") as f:
f.seek(0,2) # 从末尾开始向前移动0个字符
while True:
line = f.readline()
if len(line) == 0:
time.sleep(3)
else:
print(line.decode("utf-8"),end="")
注意:运行2的代码,在控制台实现实时监测,在运行1的代码后,在看2的控制台可以看到想要的结果。
2020年3月17日  文件日志

 八、文件的修改

# 文件a.txt内容如下,utf-8格式编码
# 张一蛋     山东    179    49    12344234523
# 李二蛋     河北    163    57    13913453521
# 王全蛋     山西    153    62    18651433422

# 要在张一蛋后面加个“<男妇女主任>”,后面的数据往后挤得效果,使用指针操作

# with open('a.txt',mode='r+t',encoding='utf-8') as f:
#     f.seek(9,0)  # utf-8格式下一个中文=3Bytes
#     f.write('<男妇女主任>')
"""
张一蛋<男妇女主任>    49    12344234523      此时的数据有部分被覆盖了,这不是我们想要的结果
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422
"""
# 强调:文本编辑工具的工作原理是:先将数据从硬盘加载到内存,修改后保存到硬盘。
# 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容。
# 2、内存中的数据是可以修改的,我们只有通过修改内存后再保存到硬盘中。
# 文件修改的两种方式
# 方式一:文本编辑采用的就是这种方式
# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
# 数据准备:创建一个c.txt文件里的内容是
""" abc def ghi"""
# with open('c.txt',mode='rt',encoding='utf-8') as f:
#     res=f.read()
#     print(res) # abc def ghi
#     data=res.replace('abc','cba')  # 使用replace()方法替换数据
#     print(data)  # 得到一个新的数据cba def ghi
# 将替换的数据写入c.txt文件内
# with open('c.txt',mode='wt',encoding='utf-8') as f1:
#     f1.write(data)

# 方式二:不想一次性全部读入内存(如果文件过大会使内存溢出)
# import os
# # 实现思路:以读的方式打开原文件(在硬盘中操作),以写的方式打开一个临时文件(在硬盘中操作),一行行读取原文件内容(将文件内容从硬盘加载到内存中),
#               修改完后写入临时文件(将内容从内存加载到硬盘)...,删掉原文件,将临时文件重命名原文件名,因为cpu执行速度太快所以人感受不到。
# # 优点: 不会占用过多的内存
# # 缺点: 在文件修改过程中同一份数据存了两份
# with open('c.txt', mode='rt', encoding='utf-8') as f, \
#         open('.c.txt.swap', mode='wt', encoding='utf-8') as f1: # .c.txt.swap临时文件.c表明隐藏
#     for line in f:
#         f1.write(line.replace('abc', 'cba'))
# os.remove('c.txt') # 删掉原文件
# os.rename('.c.txt.swap', 'c.txt')  # 将临时文件重命名原文件名
我们应该那种情况?要看情况,pycharm就是使用的第一种情况。

 

posted @ 2020-03-13 16:16  思江  阅读(368)  评论(0编辑  收藏  举报