文件操作的基本流程
我们使用Python或者其他语言编写的应用程序,当我们需要一些数据的时候,可能是数据库中的数据,也可能是计算机本身存储的数据。当我们需要应用到计算机中的数据的时候,那么我们就需要操作计算机中的文件。而Python给我们提供了文件操作的方法。文件操作有三大步流程
#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
#2. 通过句柄对文件进行操作
data=f.read()
#3. 关闭文件
f.close()
一定要记得关闭文件
当我们打开一个文件的时候,是占用了我们的内存资源的,如果我们只打开文件而不关闭,那么将会一直损耗占用我们的内存资源,直至内存资源被消耗完毕,卡死。所以,在操作完一个文件的时候,一定要关闭文件。关闭文件有两种方法:
f.close() #回收操作系统级打开的文件
del f #回收应用程序级的变量
不过, del f 一定要发生在f.close() 之后,否则就会导致操作系统大开的文件并没有关闭,而白白浪费资源。而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()。当然,每一次打开文件之后都要关闭,也就是都要f.close()。有的时候,我们会忘记关闭,那么还有一种简便的方式。极力推荐:
with open(‘a.txt’,‘w’) as f:
pass
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
data=read_f.read()
write_f.write(data)
文件编码
f=open(…)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码就是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8,所以,当我们打开文件的时候,一定要记得文件编码。
f=open(‘a.txt’,‘r’,encoding=‘utf-8’)
文件打开的模式
我们知道,在本地计算机中的文件,有一些我们可以打开阅读并修改,但有一些却只能查看,甚至不能查看。只就是我们对文件进行了设置,设置它的打开方式。在Linux中,就显得格外的明显了。那么Python操作文件的时候,也有相对应的打开模式:
-
打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则创建;存在则清空内容】
a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】 -
对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 -
+’模式(就是增加了一个功能)
r+, 读写【可读,可写】
w+,写读【可写,可读】
a+, 写读【可写,可读】 -
以bytes类型操作的读写,写读,写读模式
r+b, 读写【可读,可写】
w+b,写读【可写,可读】
a+b, 写读【可写,可读】*
文件操作的具体方法
read(3):
1. 文件打开方式为文本模式时,代表读取3个字符
2. 文件打开方式为b模式时,代表读取3个字节
其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate
注意:
-
seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
-
truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
def close(self, *args, **kwargs): # real signature unknown
关闭文件
pass
def fileno(self, *args, **kwargs): # real signature unknown
文件描述符
pass
def flush(self, *args, **kwargs): # real signature unknown
刷新文件内部缓冲区
pass
def isatty(self, *args, **kwargs): # real signature unknown
判断文件是否是同意tty设备
pass
def read(self, *args, **kwargs): # real signature unknown
读取指定字节数据
pass
def readable(self, *args, **kwargs): # real signature unknown
是否可读
pass
def readline(self, *args, **kwargs): # real signature unknown
仅读取一行数据
pass
def seek(self, *args, **kwargs): # real signature unknown
指定文件中指针位置
pass
def seekable(self, *args, **kwargs): # real signature unknown
指针是否可操作
pass
def tell(self, *args, **kwargs): # real signature unknown
获取指针位置
pass
def truncate(self, *args, **kwargs): # real signature unknown
截断数据,仅保留指定之前数据
pass
def writable(self, *args, **kwargs): # real signature unknown
是否可写
pass
def write(self, *args, **kwargs): # real signature unknown
写内容
pass
def __getstate__(self, *args, **kwargs): # real signature unknown
pass
def __init__(self, *args, **kwargs): # real signature unknown
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass
def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass
def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass
文件修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘
import os # 调用系统模块
with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
data=read_f.read() #全部读入内存,如果文件很大,会很卡
data=data.replace('www','happy') #在内存中完成修改
write_f.write(data) #一次性写入新文件
os.remove('a.txt') #删除原文件
os.rename('.a.txt.swap','a.txt') #将新建的文件重命名为原文件
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
import os
with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
for line in read_f:
line=line.replace('www','happy')
write_f.write(line)
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')
关于编码
asiic
包含数字,英文,特殊字符。利用八位表示一个字符
8位 = 1 byte 表示一个字符。
万国码unicode
将所有国家的语言包含在这个密码本。
初期:16位,两个字节,表示一个字符。
A : 00010000 00010010
中: 00010010 00010010
升级:32位,四个字节,表示一个字符。
A : 00010000 00010010 00010000 00010010
资源浪费。
utf-8
最少用8位(一个字节),表示一个字符。
英文:a :00010000 用8位表示一个字符。
欧洲:00010000 00010000 16位两个字节表示一个字符。
亚洲 中 :00010000 00010000 00010000 24位,三个字节表示一个字符。
gbk:国标
只包含:英文中文。
英文:a :00010000 8位,一个字节表示一个字符。
中文:中:00010000 00010000 16位,两个字节表示一个字符。
gb2312…
计算机单位之间的划算
8 bit = 1byte
1024byte=1kb
1024kb = 1MB
1024MB = 1GB
1024GB = 1TB
编码与解码
encode 编码 :str — > bytes
s = 'aAlice' # str
s1 = s.encode('utf-8') # bytes
encode 编码。gbk–>utf-8
s = 'hello girl'
s1 = s.encode('gbk')
print(s1)
s = '中国'
s1 = s.encode('utf-8')
print(s1)
unicode —> utf-8 编码 与解码:
s = 'alex'
s1 = s.encode('utf-8') # unicode ---> utf-8 编码
s3 = s1.decode('utf-8') # utf-8 ---> unicode 解码
print(s3)
unicode —> gbk 编码与解码:
s = 'alex'
s1 = s.encode('gbk') # unicode ---> gbk 编码
s3 = s1.decode('gbk') # gbk ---> unicode 解码
print(s3)
gbk —> utf-8
s = 'alex'
s1 = s.encode('gbk')
print(s1)
s2 = s1.decode('gbk').encode('utf-8')
print(s2)
需要说的是:Linux的操作系统默认的编码是utf-8,Windows操作系统是gbk编码,Python中默认的编码是utf-8,所以,需要注意python与Windows操作系统之间的关系。