这一章节主要讲解文件操作及其文件读取,缓存,文件指针。
文件操作
(1)文件打开:open(filepath,filemode)
filepath:要打开文件的路径
filemode:文件打开的方式
mode | 说明 | 注意 |
'r' | 只读方式打开 | 文件必须存在 |
'w' | 只写方式打开 |
文件不存在创建文件 文件存在清空内容 |
'a' | 追加方式打开 | 文件不存在创建文件 |
'r+'/'w+' | 读写方式打开 | |
'a+' | 追加和读写方式打开 |
PS:'rb','wb','ab','rb+','wb+','ab+':二进制方式打开
>>> f = open('1.txt','w') >>> type(f) <type 'file'> >>> f.close()
(2)文件写操作:
write(str):将字符串写入文件
writelines(sequence_of_strings):写多行到文件
>>> f = open('1.txt','w+') >>> f.write("123456") >>> f.close()
try: f = open('1.txt','w') f.writelines(('12','23','45')) finally: if f: f.close()
(3)文件读操作:
read([size]):读取文件(读取size个字节,默认读取全部)
readline([size]):读取一行
readlines([size]):读取完文件,返回每一行所组成的列表
try: f = open('1.txt','r') value = f.read(3) print value finally: if f: f.close() 122
try: f = open('1.txt','r') value = f.readline() print value finally: if f: f.close() 122345
迭代读取
在实际文件读取中,因为OS缓存是有限的。IO只能缓存8192Byte。
>>> import io >>> io.DEFAULT_BUFFER_SIZE 8192
如果文件超过8192Byte.直接通过readlines是不能完全读取出来了。
如果要完全读出来,使用迭代读取。
try: f = open('1.txt','r') iter_f = iter(f) lines = 0 for line in iter_f: lines+=1 print line print lines finally: if f: f.close() #1.txt有7行数据,使用迭代方式iter来将f对象迭代。 122345 1223456 12234567 122345678 1223456789 12234567890 122345678901 7
缓存机制
上一节讲到迭代读取,大家知道IO缓存最大为8192.对于IO操作来讲,缓存指的是内存缓存数据,执行之后,再从缓存写入到硬盘。
针对于IO文件write操作来讲,每次我们写入数据的时候,都是先写入缓存,执行close或者flush之后,才会真正的将缓存写入到硬盘。
所以,务必在操作完文件之后,必须最后执行f.close或者中途执行f.flush的动作。
文件指针
看下下面的例子:
try: f = open('1.txt','r+') dat = f.read(3) print dat dat = f.read(3) print dat finally: if f: f.close() 122 345
大家通过这个例子可以发现,read操作读取数据之后,再次调用读取操作,是不会从开始字节读取。这个就牵扯到文件指针的概念。
当f.read(3),文件指针就移动到第三个字节位置,当再次调用f.read(3),同样文件指针就移动到第六个字节位置。如果想要回滚会文件首部字节读取怎么办?
使用f.seek操作,先来看看seek函数的介绍:(偏移量超出文件长度就会报错)
f.seek(0, os.SEEK_SET) #移动文件指针到文件起始位置
f.seek(0, os.SEEK_END) #移动文件指针到文件末尾位置
f.seek(5, os.SEEK_CUR) #移动文件指针到当前位置的前5个字节上
f.seek(-5, os.SEEK_CUR)#移动文件指针到从文件末尾起前5个字节
try: f = open('1.txt','r+') dat = f.read(3) location = f.tell() print "location :%s" % location#标识当前文件指针的位置 print dat dat = f.read(3) location = f.tell() print "location :%s" % location#标识当前文件指针的位置 print dat finally: if f: f.close() location :3 #标识当前文件指针的位置 122 location :6 345
try: f = open('1.txt','r+') dat = f.read(3) location = f.tell() print "location :%s" % location print dat f.seek(os.SEEK_SET)#调用seek的动作 location = f.tell() print "location :%s" % location dat = f.read(3) location = f.tell() print "location :%s" % location print dat finally: if f: f.close() location :3 122 location :0 location :3 122
通过上述例子可以看出,seek动作可以将文件指针重新回到文件首部。文件指针的位置可以通过f.tell()方法知道。seek其他参数讲解大家一一去尝试操作下。
文件编码格式
try: f = open('1.txt','r+') f.write('qwer') f.write(u'博客园') finally: if f: f.close() Traceback (most recent call last): File "<pyshell#69>", line 4, in <module> f.write(u'博客园') UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
大家都知道,有时候需要在文档里面写中文。上面的写法会直接报错。那么如何写入unicode编码的字符呢?
提供两种方法:
1、直接将unicode编码字符转换为utf8编码字符保存 :unicode.encode(u'博客园','utf-8')
try: f = open('1.txt','r+') f.write('qwer') val = unicode.encode(u'博客园','utf-8') f.write(val) finally: if f: f.close() >>> try: f = open('1.txt','r+') w = f.read() print w finally: if f: f.close() qwer博客园56
2.使用codecs模块直接创建指定编码格式的文件
>>> import codecs >>> help(codecs.open) Help on function open in module codecs: open(filename, mode='rb', encoding=None, errors='strict', buffering=1).....
那我们用了实例试试:
try: f = codecs.open('5.txt','w+','utf-8') f.write(u'博客园') f.flush() finally: if f: f.close()
小结:这一章节主要讲解python的文件操作及其文件编码。