用 python 代码对文件进行各类操做。python
基本构成:vim
f = open('文件路径或者相对路',encoding='编码方式',mode='模式') # 格式构成 cotent = f.read() print(content) f.close()
代码解释:编辑器
open:函数
内置函数,open 底层调用的是操做系统的接口。测试
f:编码
变量,约定俗成的变量名有(f1,fh,file_handler,f_h),这个变量还有一个名字,叫文件句柄。对亠件进行的任何操做,都得经过文件句柄加'.'的方式。操作系统
encoding:指针
能够不写,若是不写,默认的编码本就是系统默认的编码。code
Windows: gkb视频
Linux: utf-8
MacOS: utf-8
mode:
就是定义你的操做方式:r 为读模式。
f.read():
你想操做文件,好比读文件,给文件写内容,等等,都必须经过文件句柄进行操做。
f.colse():
关闭文件。(必须关闭,不然会常驻内存。)
文件操做的三个步骤:
打开文件。
对文件句柄进行相应的操做。
关闭文件。
# 打开文件,获得文件句柄并赋值给一个变量 f = open('文件.txt', 'r', encoding='utf-8') # 默认打开模式就为 r # 经过句柄对文件进行操做 date = f.read() # 关闭文件 f.close()
报错的缘由:
UnicodeDecodeError:文件存储时与文件打开时编码本不一致。
路径分隔符产生的问题:
解决方法:在路径前加个 r r'C:\Users\Desktop\文件.txt'
文件操做的读,有四种模式(r、rb、r+、r+b),r+ 和 r+b 不经常使用, rb 操做的是非文本的文件,好比:图片、视频、音频。每种模式有五种方法(read()、read(n)、readline()、readlines()、for)。
r 模式
以只读方式打开文件,文件的指针将会放在文件的开头。是文件操做最经常使用的模式,也是默认模式,若是一个文件不设置mode,那么默认使用r模式操做文件。
举例:
f = open('文件.txt', mode='r', encoding='utf-8') msg = f.read() f.close() print(msg)
read() 一次性所有读取
read() 将文件中的内容所有读取出来; 弊端:若是文件很大就会很是的占用内存,容易致使内存崩溃。
f = open('测试', mode='r', encoding='utf-8') msg = f.read() f.close() print(msg) # 输出结果: 这是一行测试 A:这是第二行 B:这是第三行 C:这是第几行 D:这是我也不知道第几行 就这么地吧.
read(n) 指定读取到什么位置
在 r 模式下,n 按照字符读取
f = open('测试', mode='r', encoding='utf-8') msg = f.read(4) f.close() print(msg) # 输出结果: 这是一行
readline() 按行读取
readline() 每次只读取一行,注意: readline() 读取出来的数据在后面都有一个\n,解决这个问题只须要在咱们读取出来的文件后边加一个strip()就OK了
f = open('测试', mode='r', encoding='utf-8') msg1 = f.readline() msg2 = f.readline().strip() msg3 = f.readline() msg4 = f.readline() f.close() print(msg1) print(msg2) print(msg3) print(msg4) # 输出结果: 这是一行测试 A:这是第二行 B:这是第三行 C:这是第几行
readlines() 返回一个列表
readlines() 返回一个列表,列表里面每一个元素是原文件的每一行,若是文件很大,占内存,容易崩盘。
f = open('测试', mode='r', encoding='utf-8') print(f.readlines()) # 还能够这么写的,哈哈 f.close() # 输出结果: ['这是一行测试\n', 'A:这是第二行\n', 'B:这是第三行\n', 'C:这是第几行\n', 'D:这是我也不知道第几行\n', '就这么地吧.']
上面这四种都不太好,若是文件超大,内容超多,他们就很容易将内存撑爆,因此,咱们还有第五种方法。
for 循环
能够经过for循环去读取,文件句柄是一个迭代器,他的特色就是每次循环只在内存中占一行的数据,很是节省内存。
f = open('测试', mode='r', encoding='utf-8') for line in f: print(line) # 去掉 \n 能够这样写: print(line.strip()) # 这种方式就是在一行一行的进行读取,它就执行了下边的功能 ''' print(f.readline()) print(f.readline()) print(f.readline()) ....... ''' # 输出结果: 这是一行测试 A:这是第二行 B:这是第三行 C:这是第几行 D:这是我也不知道第几行 就这么地吧.
特别注意: 读完的文件必定必需要关闭
rb 模式
rb模式:以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。记住下面讲的也是同样,带b的都是以二进制的格式操做文件,他们主要是操做非文字文件:图片,音频,视频等,而且若是你要是带有b的模式操做文件,那么不用声明编码方式。
f1 = open('图片.jpeg', mode='rb') tu = f1.read() f1.close() print(tu) # 输出结果: b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00H\x00H\x00\x00\xff\xe1\x00\xb0Exif\x............后面还有.老长老长了..此处省略了.
rb模式也有read read(n) readline(),readlines() for循环这几种方法,这里就不一一演示了。
文件操做的写,有四种模式(w、wb、w+、w+b),w+ 和 w+b 不经常使用, wb 操做的是非文本的文件,好比:图片、视频、音频。操做方法是:write('要写入的内容')
w 模式
若是文件不存在,用 w 模式操做文件,它会先建立文件,而后写入内容。
f = open('这是一个新建立的文件', encoding='utf-8', mode='w') f.write('果真是一个新建立的文件') f.close()
若是文件存在,利用w模式操做文件,先清空原文件内容,在写入新内容。
f = open('这是一个新建立的文件', encoding='utf-8', mode='w') f.write('这是清空后从新写入的内容') f.close()
wb 模式
wb模式:以二进制格式打开一个文件只用于写入。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。通常用于非文本文件如:图片,音频,视频等。
>>举个例子 :
我先以rb的模式将一个图片的内容以bytes类型所有读取出来,而后在以wb将所有读取出来的数据写入一个新文件,这样我就完成了相似于一个图片复制的流程。具体代码以下:
# 第一步:将原图片经过 rb 模式读取出来。 f = open('图片.jpeg', mode='rb') content = f.read() f.close() # 第二步:将读取出来的数据经过 wb 模式写入新文件。 f1 = open('图片1.jpeg', mode='wb') f1.write(content) f1.close()
就是在文件中追加内容。这里也有四种文件分类主要四种模式:a,ab,a+,a+b,咱们只讲a
a 模式
若是文件不存在,利用a模式操做文件,那么它会先建立文件,而后写入内容。
f = open('追加文本', encoding='utf-8', mode='a') f.write('这个文件是没有的,我是新建立的') f.close()
若是文件存在,利用a模式操做文件,那么它会在文件的最后面追加内容。
f = open('追加文本', encoding='utf-8', mode='a') f.write('这是己存在的文件,我是新追加的内容') f.close()
我们还有一种模式没有讲,就是那种带+号的模式。什么是带+的模式呢?+就是加一个功能。好比刚才讲的r模式是只读模式,在这种模式下,文件句柄只能进行相似于read的这读的操做,而不能进行write这种写的操做。因此咱们想让这个文件句柄既能够进行读的操做,又能够进行写的操做,那么这个如何作呢?这就是接下来要说这样的模式:r+ 读写模式,w+写读模式,a+写读模式,r+b 以bytes类型的读写模式.........
在这里我们只讲一种就是r+,其余的大同小异,本身能够练练就好了。
#1. 打开文件的模式有(默认为文本模式): r,只读模式【默认模式,文件必须存在,不存在则抛出异常】 w,只写模式【不可读;不存在则建立;存在则清空内容】 a, 只追加写模式【不可读;不存在则建立;存在则只追加内容】 #2. 对于非文本文件,咱们只能使用b模式,"b"表示以字节的方式操做(而全部文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式) rb wb ab 注:以b方式打开时,读取到的内容是字节类型,写入时也须要提供字节类型,不能指定编码 #3,‘+’模式(就是增长了一个功能) r+,读写【可读,可写】 w+,写读【可写,可读】 a+,写读【可写,可读】 #4,以bytes类型操做的读写,写读,写读模式 r+b,读写【可读,可写】 w+b,写读【可写,可读】 a+b,写读【可写,可读】
r+ 模式 读并追加 顺序不能错
r+: 打开一个文件用于读写。文件指针默认将会放在文件的开头。
f = open('文件的读写.txt', encoding='utf-8', mode='r+') content = f.read() print(content) f.write('这是新写入的内容') f.close()
注意:若是你在读写模式下,先写后读,那么文件就会出问题,由于默认光标是在文件的最开始,你要是先写,则写入的内容会讲原内容覆盖掉,直到覆盖到你写完的内容,而后在后面开始读取。
小总结:
三个大方向:
读, 四种模式: r rb r+ r+b
写, 四种模式 : w,wb, w+,w+b
追加 四种模式: a, ab, a+,a+b
相应的功能:
对文件句柄的操做:read read(n) readline() readlines() write()
f.tell() 获取光标的位置 单位是:字节
f = open('测试', encoding='utf-8', mode='r') print(f.tell()) content = f.read() print(f.tell()) f.close() # 原文件内容 这是一行测试 A:这是第二行 B:这是第三行 C:这是第几行 D:这是我也不知道第几行 就这么地吧. # 输出结果: 0 # 开始的位置 122 # 结束的位置
f.seek() 调整光标的位置 (注意:移动单位是byte , 若是是utf-8的中文部分要是3的倍数)
f = open('测试', encoding='utf-8', mode='r') f.seek(9) content = f.read() print(content) f.close() # 原文件内容 这是一行测试 A:这是第二行 B:这是第三行 C:这是第几行 D:这是我也不知道第几行 就这么地吧. # 输出结果: 行测试 A:这是第二行 B:这是第三行 C:这是第几行 D:这是我也不知道第几行 就这么地吧.
f.flush() 强制刷新
f = open('测试', encoding='utf-8', mode='w') f.write('fafdsfsfsadfsaf') f.flush() f.close()
with open() as ....
# 优势1:不用手动关闭文件句柄 # 利用with上下文管理这种方式,它会自动关闭文件句柄。 with open('测试', encoding='utf-8', mode='r') as f: print(f.read()) # 优势2:能够加多个 open 操做 # 一个with 语句能够操做多个文件,产生多个文件句柄。 with open('测试', encoding='utf-8', mode='r') as f,\ open('测试', encoding='utf-8', mode='w') as f1: print(f.read()) f1.write('kckckckckckckkck')
这里要注意一个问题,虽然使用with语句方式打开文件,不用你手动关闭文件句柄,比较省事儿,可是依靠其自动关闭文件句柄,是有一段时间的,这个时间不固定,因此这里就会产生问题,若是你在with语句中经过r模式打开t1文件,那么你在下面又以a模式打开t1文件,此时有可能你第二次打开t1文件时,第一次的文件句柄尚未关闭掉,可能就会出现错误,他的解决方式只能在你第二次打开此文件前,手动关闭上一个文件句柄。
文件的数据是存放于硬盘上的,于是只存在覆盖、不存在修改这么一说,咱们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
文件操做改的流程:
1,以读的模式打开原文件。
2,以写的模式建立一个新文件。
3,将原文件的内容读出来修改为新内容,写入新文件。
4,将原文件删除。
5,将新文件重命名成原文件。
方式一:将硬盘存放的该文件的内容所有加载到内存,在内存中是能够修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
import os # 调用系统模块 with open('测试', encoding='utf-8') as f1,\ open('测试.bak', encoding='utf-8',mode='w') as f2: old_content = f1.read() # 所有读入内存,若是文件很大,会卡死 new_content = old_content.replace('文', 'wen') # 在内存中完成修改 f2.write(new_content) # 一次性写入新文件 os.remove('测试') # 删除原文件 os.rename('测试.bak', '测试') # 将新建的文件重命名为原文件 # 原文件内容 **文件操做改的流程:** 1,以读的模式打开原文件。 2,以写的模式建立一个新文件。 3,将原文件的内容读出来修改为新内容,写入新文件。 4,将原文件删除。 5,将新文件重命名成原文件。 # 修改后的内容 **wen件操做改的流程:** 1,以读的模式打开原wen件。 2,以写的模式建立一个新wen件。 3,将原wen件的内容读出来修改为新内容,写入新wen件。 4,将原wen件删除。 5,将新wen件重命名成原wen件。
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件(这种是经常使用的)
import os with open('测试', encoding='utf-8') as f1,\ open('测试.bak', encoding='utf-8',mode='w') as f2: for line in f1: # 一行一行的改,占内存少 new_line = line.replace('wen', '文') f2.write(new_line) os.remove('测试') os.rename('测试.bak', '测试') # 原文件内容 **wen件操做改的流程:** 1,以读的模式打开原wen件。 2,以写的模式建立一个新wen件。 3,将原wen件的内容读出来修改为新内容,写入新wen件。 4,将原wen件删除。 5,将新wen件重命名成原wen件。 # 修改后的内容 **文件操做改的流程:** 1,以读的模式打开原文件。 2,以写的模式建立一个新文件。 3,将原文件的内容读出来修改为新内容,写入新文件。 4,将原文件删除。 5,将新文件重命名成原文件。