从本篇开始准备对python文件的操作做一个系统总结。基础文件操作包括文件的文件的读取、创建、追加、删除、清空;按行进行或字节读写文件等内容。
一、python file open方法
Python 打开文件语法如下:
f = open(name[, mode[, buffering]])
各字段含义:
name: 所要打开的文件的名称,
mode:打开文件的方式:
‘r’ : 读模式 'w' : 写模式 'a' : 追加模式 'b' : 二进制模式(可添加到其他模式中使用) '+' : 读写模式(可添加到其他模式中使用) 'U' : 就是支持所有的换行模式,也就说‘\r’ '\n' '\r\n'都可表示换行,会有一个tuple用来存贮这个文件中用到过的换行符。
buffering : 是否要缓冲
0 / False : 代表无缓冲 1 / True : 代表有缓冲 大于一的数字: 代表缓冲区大小(单位是字节) -1 : 默认缓冲区大小
上面mode列出的是基本模式,实际应用中的扩展模式有:
"r" 以读方式打开,只能读文件,如果文件不存在,会发生异常。 "w" 以写方式打开,只能写文件, 如果文件不存在,创建该文件。如果文件已存在,先清空,再打开文件。 "rb" 以二进制读方式打开,只能读文件 , 如果文件不存在,会发生异常 "wb" 以二进制写方式打开,只能写文件, 如果文件不存在,创建该文件;如果文件已存在,先清空,再打开文件 "rt" 以文本读方式打开,只能读文件 , 如果文件不存在,会发生异常 "wt" 以文本写方式打开,只能写文件, 如果文件不存在,创建该文件,如果文件已存在,先清空,再打开文件 。 "rb+" 以二进制读方式打开,可以读、写文件 , 如果文件不存在,会发生异常 "wb+" 以二进制写方式打开,可以读、写文件, 如果文件不存在,创建该文件。如果文件已存在,先清空,再打开文件。
由于默认为 r 模式,如果文件不存在,则会发生异常提示。
二、字节读取
1、read
f.read(num) //读出num个字节 f.read() //读出全部字节
2、write
f.write(string) //将string写入文件
三、行读写
F.readline([size]) #读一行,如果定义了size,size的单位是byte,有可能返回的只是一行的一部分 F.readlines([size]) #把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。 F.write(str) #把str写到文件中,write()并不会在str后加上一个换行符 F.writelines(seq) #把seq的内容全部写到文件中。这个函数也只是忠实地写入,不会在每行后面加上任何东西。
四、其他方法
- F.close() #关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。如果一个文件在关闭后还对其进行操作会产生ValueError
- F.flush() #把缓冲区的内容写入硬盘
- F.fileno() #返回一个长整型的”文件标签“
- F.isatty() #文件是否是一个终端设备文件(unix系统中的)
- F.tell() #返回文件操作标记的当前位置,以文件的开头为原点
- F.next() #返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。
- F.seek(offset[,whence]) #将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。但如果提供了whence参数就不一定了,whence可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意,如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。
- F.truncate([size]) #把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。如果size比文件的大小还要大,依据系统的不同可能是不改变文件,也可能是用0把文件补到相应的大小,也可能是以一些随机的内容加上去。
五、示例
1、读取所有内容
file_object = open('png.sh') try: all_the_text = file_object.read() print all_the_text,type(all_the_text) finally: file_object.close( )
2、读固定字节
file_object = open('abinfile', 'rb') try: while True: chunk = file_object.read(100) if not chunk: break do_something_with(chunk) finally: file_object.close( )
3、行读取
with open('foo.txt', 'r') as f: for line in f.readlines(): # do_something(line) 和 with open('foo.txt', 'r') as f: for line in f: # do_something(line)
从Python 2.3开始,Python中的文件类型开始支持迭代功能,比如下面两段代码做的其实差不多:
但是,后面一种迭代占用更小的内存,而且更加智能(依赖于Python文件对象的实现),所需文件内容是自动从buffer中按照需要读取的,是值得鼓励的做法。
file.readlines()是把文件的全部内容读到内存,并解析成一个list,当文件的体积很大的时候,需要占用很多内存,使用该方法是一种不明智的做法。
还有一个file.xreadlines()方法,则直接返回一个iter(file)迭代器,在Python 2.3之后已经不推荐这种表示方法了。
4、写文件
#写文本文件 output = open('data', 'w') #写二进制文件 output = open('data', 'wb') #追加写文件 output = open('data', 'w+') #写数据 file_object = open('thefile.txt', 'w') file_object.write(all_the_text) file_object.close( ) #写入多行 file_object.writelines(list_of_text_strings)
注意,调用writelines写入多行在性能上会比使用write一次性写入要高。
写入文件时换行符的处理:
sample_list = [line+'\n' for line in sample_list] outfile.wirtelines(sample_list)
5、综合示例
#! /usr/bin/python import os,sys try: fsock = open("D:/pytest/test.py", "r") except IOError: print "The file don't exist, Please double check!" exit() print 'The file mode is ',fsock.mode print 'The file name is ',fsock.name P = fsock.tell() print 'the postion is %d' %(P) fsock.close() #Read file fsock = open("D:/pytest/test.py", "r") AllLines = fsock.readlines() #Method 1 for EachLine in fsock: print EachLine #Method 2 print 'Star'+'='*30 for EachLine in AllLines: print EachLine print 'End'+'='*30 fsock.close() #write this file fsock = open("D:/pytest/test.py", "a") fsock.write(""" #Line 1 Just for test purpose #Line 2 Just for test purpose #Line 3 Just for test purpose""") fsock.close() #check the file status S1 = fsock.closed if True == S1: print 'the file is closed' else: print 'The file donot close'
六、python读写大文件
实际应用中经常会遇到这样的情况,一台主机的物理内存只有2G,而文件大小有10G 。一次读取文件时,肯能会报memoryError错误。遇到这种问题时解决方法有两种:
文件块切割
将大文件分割成若干小文件处理,处理完每个小文件后释放该部分内存。具体如下:
def readInChunks(fileObj, chunkSize=1024*1024*200): """ Lazy function to read a file piece by piece. Default chunk size: 200MB. """ while True: data = fileObj.read(chunkSize) if not data: break yield data f = open('bigFile') for chuck in readInChunks(f): do_something(chunk)
比如上面的方法中就将文件切割成200M大小的块。再进行读取操作。
提到读,还有写大文件的问题,网上看到通过使用模块mmap 来实现。
参考页面:
python中的readlines和xreadlines函数
想要了解更多,可以pydoc file 查看python file操作帮助文档。