首先要明确的就是 python 对文件的操作实质上是需要调配两种资源:
1, 宿主机的系统资源, 比如 Linux 下的 limit 文件句柄数
2,python 内存资源
两种使用方法:
方式一:
- f=open('aaa.txt','rt',encoding='utf8')
- f.read()
- f.close ## 释放系统资源, 向系统发送指令告知, 程序结束, 请求系统关闭文件
方式二:
- with open('aaa.txt','rt',encoding='utf8') as f:
- f.read()
ps: 方式二借助 with 语句会在操作完后自动释放文件, 而方式一需要手动, 为了防止遗忘, 建议使用方式二,
文件如果忘记 colse 会经过一段时间系统自动释放, 但是对于系统来讲优势并发请求较高就会有影响, 因为系统有
默认最大打开文件数, 比如 Linux 是 1024 个, 如果等待系统周期释放可能 1024 个早就用完了
两种文件模式:
t 文本模式, 默认, 仅适用与字符文件也就是和字符编码相关的文件, 并不适合图片和音频等与字符编码无关的文件
b 二进制模式, 也就是 bytes 模式, 一些文件在硬盘中的存在都是 bytes 形式
文件的读写模式:
r 只读模式, 系统默认, 在此模式下只能读操作, 若找不到文件则报错
w 只写模式, 在此模式下只允许写操作, 但是本次文件操作结束 (close) 后, 第二次进行文件操作则清空第一
次写入的文件内容重新依次写入, 第三次则继往开来, 默认文件不存在则创建
a 只追加模式, 每次写入都从上次写入结束的位置, 不擦除以前的内容, 默认文件不存在则创建
r+ 表示可以同时读写某个文件, 文件不存在依然报错
w+ 表示可以同时读写某个文件
a+ 表示可以同时读写某个文件
默认模式: rt 模式
对比 t 和 b 两种模式的输出:
分别打印两种模式下的结果:
test.txt 内容: 哈哈哈
t 模式
- with open('test.txt','rt',encoding='utf8') as f:
- print(f.read())
结果: 哈哈哈
b 模式
- with open('test.txt', 'rb') as f:
- print(f.read())
结果: b'\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88'
- with open('test.txt', 'rb') as f:
- print(f.read().decode('utf-8'))
结果: 哈哈哈
ps: 在指定模式后, t 模式指定字符编码, 不指定字符编码容易出现乱码, 我们一般现在使用 UTF-8 文件, 如果不
指定编码读在 windows 下将默认系统以 gbk 去读取, 就会出现乱码, 在 b 模式下无需指定, 但是默认打印出是
字节模式, 如果想看内容, 可以 dcoding 进行解码
打开文件的方式:
一次打开一个文件:
- with open(r'test.txt', 'rb') as f1:
- f1.read()
一次打开多个文件:
- with open(r'test.txt', 'rb') as f1,open('test.txt', 'rb') as f2:
- f1.read()
- f2.read()
文件的路径:
相对路径: r'test.txt'
绝对路径: r'D:\python\Day04\test.txt'
注意事项: windows 下路径的斜杠有转义的意思, 在路径前写'r'取消转义, 增加程序的跨平台性
文件操作有哪些方法:
- # f.read() ## 将文件内容一次性读出, 对内存消耗比较大
- # f.readline() ## 将文件内容一次读出一行, 再次执行 f.readline()则读出第二行, 依次类推, 对内存消耗比较小
- # f.readlines() ## 将每一行内容读入到一个列表中
- # f.write() ## 写入文件
- # f.writelines() ## 根据一个列表, 等能被 for 循环的类型一次写入. 比如 str,tulep,dict,set 等, str 下由于'hello'里面 for 的结果没有 \ n 所以会看似像是没有被切分'
- # f.close() ## 关闭文件
- # f.readable() ## 判断是否可读
- # f.writable() ## 判断是否可写
- # f.closed ## 判断文件是否关闭
- # f.flush() ## 立刻将文件内容从内存刷到硬盘
- # f.name ## 打印文件名
修改文件操作的原理:
方式一:
- #1, 先将文件内容全部读入内存
- #2, 在内存中修改完毕
- #3, 将修改的结果覆盖写回硬盘
- # 优点: 在修改期间硬盘上同一时刻只有一份数据
- # 缺点: 占用内存过高
- # with open('db.txt',mode='rt',encoding='utf-8') as f:
- # data=f.read()
- # new_data=data.replace('alex','alexdsb')
- # print(new_data)
- #
- # with open('db.txt',mode='wt',encoding='utf-8') as f:
- # f.write(new_data)
- #
方式二:
- # 一行一行的读, 一行一行的改:
- #1, 以读的模式打开源文件, 以写的模式打开一个临时文件
- #2, 然后用 for 循环读取原文件一行行内容, 每读一行则修改一行, 将修改的结果写入临时文件, 直到把源文件都遍历完
- #3, 删除原文件, 将临时文件重命名为原文件名
- # 优点: 同一时刻在内存中只存在文件的一行内容
- # 缺点: 在修改期间硬盘上同一份数据会保存两份
- import os
- with open('db.txt',mode='rt',encoding='utf-8') as src_f, open('.db.txt.swap',mode='wt',encoding='utf-8') as temp_f:
- for line in src_f:
- if 'alex' in line:
- line=line.replace('alex','alexdsb')
- temp_f.write(line)
- os.remove('db.txt')
- os.rename('.db.txt.swap','db.txt')
答疑: 看完这个过程你可能会有些疑惑既然有节约内存的方法二, 为什么还用方式一呢, 是因为方式一能一次性把内容全部打印出来, 供用户阅读修改
而方法二只能一次出一行, 对于现实生活中不太适合, 而对于程序来说十分高效
写一个 cp 小脚本:
- # cp 小脚本考虑到针对不同类型文件进行复制, 直接使用 b 模式, 因为一些文件在硬盘中的存在都是 bytes 形式, 而使用 t 是无法解析和复制 mp4 格式的
- import sys
- src_file=sys.argv[1] ##python 文件后跟的第一个参数
- dst_file=sys.argv[2] ## 第二个参数
- with open(src_file,'rb') as f1,open(dst_file,'wb') as f2:
- for line in f1:
- f2.write(line)
来源: http://www.bubuko.com/infodetail-2678963.html