文件处理

一 文件操做

注操做文件的流程:python

#1. 打开文件,获得文件句柄并赋值给一个变量
#2. 经过句柄对文件进行操做
#3. 关闭文件

 f=open('a.txt','r')的过程分析linux

#一、由应用程序向操做系统发起系统调用open(...)

#二、操做系统打开该文件,并返回一个文件句柄给应用程序

#三、应用程序将文件句柄赋值给变量f

强调!!!vim

#强调第一点:
打开一个文件包含两部分资源:操做系统级打开的文件+应用程序的变量。在操做完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
一、f.close() #回收操做系统级打开的文件
二、del f #回收应用程序级的变量

其中del f必定要发生在f.close()以后,不然就会致使操做系统打开的文件尚未关闭,白白占用资源,
而python自动的垃圾回收机制决定了咱们无需考虑del f,这就要求咱们,在操做完毕文件后,必定要记住f.close()

虽然我这么说,可是不少同窗仍是会很不要脸地忘记f.close(),对于这些不长脑子的同窗,咱们推荐傻瓜式操做方式:使用with关键字来帮咱们管理上下文
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')

python2中的file与openwindows

#首先在python3中操做文件只有一种选择,那就是open()

#而在python2中则有两种方式:file()与open()
二者都可以打开文件,对文件进行操做,也具备类似的用法和参数,可是,这两种文件打开方式有本质的区别,file为文件类,用file()来打开文件,至关于这是在构造文件类,而用open()打开文件,是用python的内建函数来操做,咱们通常使用open()打开文件进行操做,而用file当作一个类型,好比type(f) is file

 

 

二 打开文件的模式

文件句柄 = open('文件路径', '模式')


#1. 打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则建立;存在则清空内容】
a, 之追加写模式【不可读;不存在则建立;存在则只追加内容】

#2. 对于非文本文件,咱们只能使用b模式,"b"表示以字节的方式操做(而全部文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb 
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也须要提供字节类型,不能指定编码

#3. 了解部分
"+" 表示能够同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
a+, 写读【可读,可写】


x, 只写模式【不可读;不存在则建立,存在则报错】
x+ ,写读【可读,可写】
xb

 

三 操做文件方法

#掌握
f.read() #读取全部内容,光标移动到文件末尾
f.readline() #读取一行内容,光标移动到第二行首部
f.readlines() #读取每一行内容,存放于列表中

f.write('1111\n222\n') #针对文本模式的写,须要本身写换行符
f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,须要本身写换行符
f.writelines(['333\n','444\n']) #文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

#了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #若是文件打开模式为b,则没有该属性
f.flush() #马上将文件内容从内存刷到硬盘
f.name

四 文件内光标移动

一: read(3):

  1. 文件打开方式为文本模式时,表明读取3个字符

  2. 文件打开方式为b模式时,表明读取3个字节

二: 其他的文件内光标移动都是以字节为单位如seek,tell,truncate

注意:

  1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但不管哪一种模式,都是以bytes为单位移动的

  2. truncate是截断文件,因此文件的打开方式必须可写,可是不能用w或w+等方式打开,由于那样直接清空文件了,因此truncate要在r+或a或a+等模式下测试效果
    
  刚打开文件就调用它会清空文件。

五 文件的修改

文件的数据是存放于硬盘上的,于是只存在覆盖、不存在修改这么一说,咱们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:编辑器

方式一:将硬盘存放的该文件的内容所有加载到内存,在内存中是能够修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)函数

 

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #所有读入内存,若是文件很大,会很卡
    data=data.replace('alex','SB') #在内存中完成修改

    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('alex','SB')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

 

六 本身的一些收集

linux上处理windows上的文件时最好用 rb wb,还有进行文件传输的时候也要用b(二进制),避免 编码方式的不一样致使错误,并且文件中不止文本有图片等的状况会出错.b模式跨平台,由于全部系统存储数据都是二进制.编码

 

1.python 2.x中:
默认都是读取文本文件,而且是ASCII编码的文本文件。要读取二进制文件,好比图片、视频等等,
用'rb'模式打开文件便可:

>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

字符编码:读取非ASCII编码的文本文件,就必须以二进制模式打开,再解码。好比GBK编码的文件:
>>> f = open('/Users/michael/gbk.txt', 'rb')
>>> u = f.read().decode('gbk') #将二进制解码,存文件encode,读取文件decode
>>> u
u'\u6d4b\u8bd5'
>>> print u
测试

 

6.1文件读写注意:文件写入的是字符串,不能这样

a = [1,2,3]
f.write(a)
不能f.write(5)

f = open(‘1.txt’,’w’,’buffersize’),其实跟file是同样的,是file的别名。 文件打开的过程当中不能更改模式,除非r+或者w+模式。spa

 with open('1.txt','w','buffersize') as f:
     f.write('aaa')  #w模式不会自动换行,须要加上 \n,a 模式会自动加上\n
     f.writelines(['12\n''34\n'])
     f.close() #关闭文件,with模式下不用,会自动关闭。

     f.seek(-1,2), 从文件末尾为原点计算,读取倒数第一个字符
     f.read()
     f.readline()
     f.readlines() 读取整个文件为列表,将文件所有读取到内存

     f.xreadlines() 一行一行读取到内存中,处理大文件必需要用它,不要用readlines。
     f.write()
     f.writeline()
     f.truncate()  #截取文件,默认截取到当前位置。刚打开文件就调用它会清空文件。
     f.flush()  #将文件内存中的内容写到磁盘

 注意:linux上处理windows上的文件时最好用 rb   wb,还有进行文件传输的时候也要用b(二进制),避免编码方式的不一样致使错误。


 f = file('1.txt','w')    #帮助  help(file),跟open是同样的

操做方法同上


 f = file('test.txt','r')
 遍历文件
     for line in f.xreadlines(): #大文件必须用xreadlines()一行一行读
         print line,   #加上,  不打印换行符

 

6.2文件内容更改

fileinput模块提供处理一个或多个文本文件的功能,能够经过使用for循环来读取一个或多个文本文件的全部行。

【默认格式】

    fileinput.input (files='filename', inplace=False, backup='', bufsize=0, mode='r', openhook=None)

    files:         #文件的路径列表,默认是stdin方式,多文件['1.txt','2.txt',...]
    inplace:       #是否将标准输出的结果写回文件,默认不取代
    backup:        #备份文件的扩展名,只指定扩展名,如.bak。若是该文件的备份文件已存在,则会自动覆盖。
    bufsize:       #缓冲区大小,默认为0,若是文件很大,能够修改此参数,通常默认便可
    mode:      #读写模式,默认为只读
    openhook:    #该钩子用于控制打开的全部文件,好比说编码方式等;

【经常使用函数】


    1 fileinput.input()       #返回可以用于for循环遍历的对象
    2 fileinput.filename()    #返回当前文件的名称
    3 fileinput.lineno()      #返回当前已经读取的行的数量(或者序号)
    4 fileinput.filelineno()  #返回当前读取的行的行号
    5 fileinput.isfirstline() #检查当前行是不是文件的第一行
    6 fileinput.isstdin()     #判断最后一行是否从stdin中读取
    7 fileinput.close()       #关闭队列

实例:替换Rain为Jerry

    for line in fileinput.input('user.txt',backup='.bak',inplace=1):
        line = line.replace('Rain','Jerry')
        print line,

实例:向文件中指定位置插入内容操作系统

def file_insert(fname, str):
    r = ur'}'
    f = open(fname)
    old = f.read()
    num = int(re.search(r, old).start()) #正则找到要插入到的位置。

    f_input = fileinput.input(fname, inplace=1)
    #for line in fileinput.input(fname, inplace=1):
    for line in f_input:
        if r in line:
            print line.rstrip() #让stdout被重定向到输入文件里
            print "\n"+str+"\n" #让stdout被重定向到输入文件里,str是要插入的内容
            f.seek(num+2) #移动到插入位置末尾。
            print f.read() #让stdout被重定向到输入文件里,将剩余的内容打印
            break
        else:
            print line.rstrip()
    f.close()
    f_input.close()
    #print "OK! The %s configure has been sucessfull added!" % fname
    print "Ok! 配置文件%s已经添加成功!" % fname

注意: fileinput.input的inplace必需要设为1,以便让stdout被重定向到输入文件里。

6.3大文件迭代方法:

1.while + readline
f = open('text.txt',r)
while true:
    line = f.readline()  一行一行读取,每读取一行文件指针移动到下一行
    if line:
        pass
     else:
        break

2.xrandlines()

3.文本文件自带的迭代:
f = open('text.txt',r)
for i in f:
    pass

4.用yield生成器。

6.4核心笔记:保留分行符

当使用输入方法如read()或者readlines()从文件度取行时,python不会删除结束符。文件写操做同样不会写入 结束符号(n).

 

行分隔符和其它文件系统的差别:不一样操做系统所支持的行分隔符,路径分隔符,都不一样。为了有助于跨平台开发, os模块的如下属性,在不一样平台会自动设置成相应的值。

>>> import os
>>> os.linesep
'\n'
>>> os.pathsep
':'
>>> os.sep
'/'
>>> os.curdir
'.'
>>> os.pardir
'..'
>>>

6.5标准文件: sys.stdin sys.stdout sys.stderr

标准输入:通常是键盘。stdin对象为解释器提供输入字符流,通常使用raw_input()和input()函数。 name = sys.stdin.readline() 至关于 raw_input()

标准输出:通常是屏幕。stdout对象接收到print语句产生的输出。 sys.stdout.write()方法其实就是上面所讲的标准输出,print语句就是调用了这个方法

错误输出:通常是错误信息。stderr对象接收出错的信息。

实例:从控制台重定向到文件。

记住,若是你还想在控制台打印一些东西的话,最好先将原始的控制台对象引用保存下来, 向文件中打印以后再恢复 sys.stdout:

_console__ = sys.stdout #保存原始控制台

import sys

f_handler=open('out.log', 'w')
sys.stdout=f_handler     #标准输出重定向到文件
print 'hello'
print 'hello'
print 'hello'
f_handler.close()

sys.stdout= __console__  #恢复控制台
print 'console'
相关文章
相关标签/搜索