文件
- 文件:存储在外部介质(如:硬盘)上的数据或信息的集合。
- 作用:以硬盘为载体,把程序中的数据可以保存在文件中,可以做到永久存储,防止数据丢失。
数据能够永久存储常见有两种方式
- 使用文件存储
- 数据库(数据库的读写性能比较高,速度快)
- 文本文件:一般指只有字符编码存储的文件,能够被最简单的文本编译器直接读取。
- 多行文本,用
\n
表示换行
编码
- 编码:信息从一种形式转换为另一种形式的过程
- 常用的编码:
- ASCII, Unicode, UTF-8…
- 中文编码:
- GB2312、GBK、BIG5… → UNICODE字符集
- 声明编码,文件类型统一
# -*- coding: utf-8 -*-
- 头疼的命令行下的中文
cp936
(就是GBK
) - Python3默认
UTF-8
- 所以可以使用中文变量名
- 文件对象的编码
- 在
Windows
里面,Python解释默认读取文件的编码格式是GBK
(一个汉字占两个字节),在mac
和linux
默认读取文件的编码格式是utf-8
(一个汉字占3个字节) cp936 -> gbk
cp936
就是gbk
,可以百度
- 在
# 查看文件编码格式
print(file.encoding)
# 把二进制(字节数据)转成字符串
# decode表示对二进制数据进行解码转成字符串,默认是按照utf-8进行解码
b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode("utf-8") # 你好
# 把字符串转化成二进制(字节数据)
'你好'.encoding('UTF-8') # b'\xe4\xbd\xa0\xe5\xa5\xbd'
'你好'.encoding('gbk') # b'\xc4\xe3\xba\xc3'
从编码就可以看出来:
utf-8
一个汉字对应3个字节,一个字母对应一个字节;gbk
一个汉字对应2个字节,一个字母对应一个字节。
生成文件对象
- 文件对象\读取\写入\文件指针
fileobject = open(filename, mode) # [2,3版中都用]
fileobject = file(filename, mode) # [2中才有]
文件操作流程
- 步骤:打开文件→操作文件(读写等)→关闭文件
- 打开文件:建立文件与程序的关联
open(filename, mode)
filename
:文件名(包括路径);
mode
:打开模式
打开模式 | 含义 |
---|---|
r | 只读,文件不存在则报错 |
w | 只写,重置文件,文件不存在则自动创建 |
a | 末尾追加,文件不存在则自动创建 |
+ | 更新(替换) |
r+ | 读写,读权限优先,即文件不存在则报错写的是时候,指针在文件头,写一个字符覆盖一个字符(好比insert 模式) |
w+ | 读写,写权限优先,即文件不存在则自动创建 |
b | 打开二进制的文件,可以与r\w\a\+ 结合时候用 |
U | 支持所有的换行符号"\r ", “\n ”, “\r\n ” |
重点看指针的位置
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
- 操作文件:写入、读取…
- 写入操作:从计算机内存向文件写入数据
write()
:将文本数据写入文件中writelines()
:将字符串列表写入文件中
- 关闭文件:终止程序与文件的关联
close()
文件对象的方法
方法 | 用法 | 说明 |
---|---|---|
read | String = FileObject.read([size]) | 读出文件的所有内容,并赋值给一个字符串 size :读出文件的前[size] 个字符,并输出给字符串,此时文件的指针指向size 处 |
readline | String = FileObject.readline([size]) | 每次读取文件的一行(文件中的\n 会被翻译成\\n )size :是指每行每次读取size 个字节,直到行的末尾 |
readlines | list = FileObject.readlines([size]) | 多行读,返回一个列表,每行是一个元素,并且每项是以换行符为结尾的一行字符串 size :每次读入size 个字符,然后继续安size 读,而不是每次读入行的size |
write | FileObject.write(string) | write 和后面的writelines 在写入前是否清除文件中原来所有的数据后再写入新的内容,取决于打开文件的模式 |
writelines | FileObject.writelines(List) | 多行写效率比write 高,速度快,少量写入可以使用write |
next | next(FileObject) | 返回当前行,并将文件指到下一行(和readline 差不多) f = open('1.txt', 'r', encoding='UTF-8')for i in range(9): print(next(f))f.close() 遍历超过文件的行数,会报错 |
flush | FileObject.flush() | 提交更新(不针对读取操作),简单说就是对文件写入、追加操作后,close 之前,此时打开文件会发现,内容并没有变化(内容暂存在内存中),此时调用flush ,文件内容就更新了 |
seek | Fileobject.seek(偏移量,选项) | [打开文件的时候要以二进制的形式(rb )打开,才能用1/2 等分数] 选项=0 时,表示将文件指针指向从文件头部到"偏移量"字节处 选项=1 时,表示将文件指针指向从文件的当前位置,向后移动"偏移量"字节 选项=2 时,表示将文件指针从文件的尾部,向前移动"偏移量"字节 |
close | FileObject.close() | 关闭打开的文件每次调用都需要使用 |
读取操作
- 从文件中读取数据到计算机内存中。
- 以字符串方式读取文件中的数据,文件操作的模式是“
r
”; - 以字节方式读取文件中的数据,文件操作的模式是“
rb
”; - 注意:
- a.表示能够读取文本文件数据,如:.txt,不能够读取视频、图片、音乐等文件。
- b.读取文件的时候,文件必须存在。
file = open("087文件的读取.py", "r", encoding="utf-8")
# 查看文件编码格式
print(file.encoding) # utf-8,encoding是UTF-8,这里就输出UTF-8
# 使用read方法,表示把文件中的所有数据都读取出来
result = file.read()
# 这里3表示读取的是3个字符串长度的数据
# file_data = file.read(3)
print(result)
# 关闭文件,一定要关闭文件,释放文件对象内存
file.close()
# 如果文件的操作模式里面带有b这个模式,那么就不需要指定encoding这个参数
file = open("087文件的读取.py", "rb")
result = file.read()
# 这里3表示读取的是3个字节长度的数据,
# 在utf-8编码格式下,一个字母占用一个字节,一个汉字占用三个字节
# file_data = file.read(3)
print(result, type(result))
# 扩展: 把二进制(字节数据)转成字符串
file_data = result.decode("utf-8")
print(file_data, type(file_data))
file.close()
# 读取一行数据使用readline
file = open("087文件的读取.py", "r", encoding="utf-8")
# 只读取第一行数据, 遇到换行表示一行数据,换行符是结束读取一行的标识符
result = file.readline()
print(result)
file.close()
# 读取多行数据
file = open("087文件的读取.py", "r", encoding="utf-8")
# 读取文件中的所有行数据, 返回的数据是一个列表类型
result = file.readlines()
print(result)
for row in result:
print(row, end="")
file.close()
文件的遍历
# 方式一:利用读取多行
f = open('tmp.txt', 'r')
for line in f.readlines():
# 处理一行数据
pass
f. close()
# 方式二:和方式一效果相同★
f = open('tmp.txt', 'r')
for line in f:
# 处理一行数据
pass
f. close()
写入操作
- 以字符串方式写入数据到文件,文件操作模式是“
w
”; - 以二进制(字节)方式写入数据到文件, 文件操作模式是“
wb
”。 - 注意:
- a.如果文件不存在,那么会先把文件创建出来,然后写入指定数据;
- b.如果文件存在,那么打开文件的时候先把文件的数据清空,然后写入指定数据,文件中的之前的数据不保留。
file = open("088文件的写入.txt", "w", encoding="utf-8")
# 查看编码格式
print(file.encoding)
# 写入字符串数据
file.write("hello1\n")
file.write("world1")
file.write("哈哈")
# 关闭文件
file.close()
# 如果文件操作模式中带有b模式,那么就不能指定encoding这个参数了
file = open("2.txt", "wb")
# 把字符串转成二进制,encode方法,默认的编码格式是utf-8(可省略)
data = "hello哈哈".encode("utf-8")
print(data, type(data))
file.write(data)
file.close()
追加写入
a
表示以字符串方式追加写入到文件- 注意:
(w, wb, a, ab)
写入数据到文件,如果文件不存在会自动创建一个文件
file = open("089文件的追加写入.txt", "a", encoding="utf-8")
# 追加写入数据
file.write("你好")
# 关闭文件
file.close()
# ab: 表示以二进制方式追加写入到文件
file = open("089文件的追加写入.txt", "ab")
# 对字符串数据进行编码,把字符串转成二进制写入到文件
data = "哈哈".encode("utf-8")
# 追加写入数据
file.write(data)
# 关闭文件
file.close()
文件的拷贝
小文件的拷贝
# 原文件的名字
src_file_name = "test.txt"
# 把原文件名根据“.”分割成三部分,可本文搜索“partition”
file_name, point, extension = src_file_name.partition(".")
# 目标文件的名字test[复件].txt
dst_file_name = file_name + "[复件]" + point + extension
# 1.打开原文件:为了兼容其它文件类型的数据,我们使用rb模式
src_file = open(src_file_name, "rb")
# 读取原文件中的所有数据
src_file_data = src_file.read()
# 2. 打开目标文件(拷贝后的文件)
dst_file = open(dst_file_name, "wb")
# 把原文件中的二进制数据写入到目标文件(拷贝后的文件)
dst_file.write(src_file_data)
# 关闭文件
src_file.close()
dst_file.close()
大文件的拷贝
- 为了防止内存暴涨,有可能导致内存溢出,我们需要循环读取文件中的数据,每次读取指定数据。
- 为什么可以把
if len(src_file_data )>0
: 直接写成if src_file_data :
?本文搜索“分支语句”中的“if语句的扩展”。
# 将上个程序read()改成按规定字节循环读取,当让打开新文件需要提到循环前。
while True:
src_file_data = src_file.read(1024)
if src_file_data:
# 表示读取到文件中的数据了,把读取到的数据写入到目标文件
# 把原文件中的二进制数据写入到目标文件(拷贝后的文件)
dst_file.write(src_file_data)
else:
# 表示文件中的数据读取完成了
break
with
操作
with open(filepathname, mode) as f:
f.xxxx()
使用with
语句,不管处理文件过程中是否发生异常,都能保证with
语句执行完毕后关闭文件,不需要单独的f.close()
语句。
with
操作的原理查看“Python
进阶学习笔记”中的“上下文管理器”。