文件操作
冯诺依曼体系架构
CPU由运算器和控制器组成
运算器,完成各种算数的运算,逻辑运算,数据传输等数据加工处理
控制器,控制程序的执行
存储器,用于记忆程序的数据,列如内存
输入设备,将数据或者程序输入到计算机中列如键盘 鼠标
输出设备,将数据或者程序的处理结果展示给用户,列如显示器,打印机等等
一般说的IO操作,指的是文件的IO,如果是指网络的IO都会直接说网络IO
文件的IO常操作
open—-打开 read—-读取 写入—-write close—–关闭
readline—行读取 readlines—-多行读取 seek—-文件指针操作 tell—指针位置
打开操作
open(file,mode=’r’,buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)
打开一个文件,返回一个文件对象和文件的描述符。打开文件失败,则返回异常
基本使用:
创建一个文件test,然后打开它,用完关闭
f = open(‘test’)
print(f.read())
f.close()
文件操作中,最常用的操作就是读写
文件的访问操作的模式有两种:文本模式和二进制模式。不同的模式下,函数的操作不尽相同。表现结果也不一样
open的参数
file 打开或者要创建的文件名,如果指定路径。默认是当前路径
Mode模式
r 缺省的,表示只读打开
w 只写打开
x 创建并写入一个新的文件
a 写入打开,如果文件存在,则追加
b 二进制模式
t 缺省的文本模式
+ 读写打开一个文件,给原来只读只写方式打开提供缺失的读或者写的能力
练习:
#r模式
f = open(‘test’,’r+’)
f.read()
f.write(‘abc’)
f.close()
print(f)
f = open(‘test’,’w+’)
f.read()
f.write(‘123’)
f.close()
open默认是只读模式r打开已经存在的文件
R
只读打开文件,则用write方法会抛异常
如果文件不存在,抛出FileNotFoundError异常
W
如果只写方式打开,如果读则抛出异常
如果文件不存在,则直接创建文件
如果文件存在,则清空文件内容
f = open(‘test1′,’x’)
f.write(‘abc’)
f.close()
X
文件不存在则创建文件,并以只读方式打开
文件存在,抛出FileExisError异常
A
文件存在。只写打开,追加内容
文件不存在,则创建后,只写打开,追加内容
r是只读,wxa都是只写
Wxa都可以产生新的文件w不管文件存在与否,都会生成全新内容得文件,a不管文件是否存在,都能在打开的文件内部追加,x必须要求文件事先不存在,自己创造一个新的文件
文本模式t
字符流,将文件的的字节按照某种字符编码理解,按照字符操作,open的默认mode就是rt
二进制模式b
字节流,将文件就按照字节理解,与字符编码无关,二进制模式操作时,字节操作使用bytes类型
f = open(“test”,’rb’)
s = f.read()
print(type(s))
print(s)
f.close()
f = open(‘test’,’wb’)
s = f.write(“马哥教育”.encode())
print(s)
f.close()
f = open(“test”,’r+’)
s = f.read()
f.write(“马哥教育”)
print(f.read())
f.close()
+
为 r,w,a,x提供缺失的读写功能,但是,获取的文件对象依旧按照r,w,a,x自己的特征。+不能单独使用,可以认为他是为前面的模式字符做增强功能的
文件指针
上面的例子中,已经说明了有一个指针
文件指针,指向当前字节位置
mode=r 指针的起始位置在0
mode=a 指针的起始位置在EOF
tell()显示指针当前的位置
seek(offset[,whence])
移动文件指针位置,offest偏移多少字节,只能是正整数
文本模式下
whence 0 缺省值,表示从头开始,offest只能是正整数
whence 1 表示从当前位置,offest只接受0
whence 2 表示从EOF开始,offest只接受0
文本模式支持从头开始向后偏移的方式
Whence为1表示从当前位置开始偏移,但是只支持偏移0,相当于原地不动,所以没什么用
Whence为2表示从EOF开始,只支持偏移0,相当于移动文件指针到EOF
Seek是按照字节偏移的
二进制模式下
Whence 0 缺省值,表示从开头开始,offest只能说正整数
Whence 1 表示从当前位置,offest可正可负
Whence 2 表示从EOF开始,offes可正可负
二进制模式支持任意起点的偏移,从头,丛尾,从中间位置开始
向后seek可以超界,但是向前seek的时候不能超界,不能超界,否则抛异常
Buffering:缓冲区
-1 表示使用缺省大小的buffer,如果是二进制模式,使用io.DEFAULT_BUFFER_SIZE值,默认是4096或者8192.如果是文本模式,如果是文本模式,如果是终端设备,是行缓寸模式,如果不是,则使用二进制模式策略
0只在二进制模式使用,表示关buffer
1 只在文本模式使用,表示行缓冲,意思就是见到换行符就flush
大于1用于指定buffer的大小
Buffer缓冲区
缓冲区一个内存空间,一般来说是一个FIFO队列,到了缓冲区慢了或者达到阈值,数据才会flush到磁盘
Flush()将缓冲区数据写入磁盘
Close()关闭前会调用flush()
Io.DEFAULT.BUFFER_SIZE缺省缓冲区大小字节
二进制模式
import io
f = open(‘test’,’w+b’)
print(io.DEFAULT_BUFFER_SIZE)
f.write(“magedu.com”.encode())
f.seek(0)
f.write(“www.magedu.com”.encode())
f.flush()
f.close()
f = open(“test4″,’w+b’,4)
f.write(b”mage”)
f.write(b”du”)
f.close()
文本模式
f = open(“test”,’w+’,1)
f.write(“mag”)
f.write(“magedu”*4)
f.write(‘\n’)
f.write(“hello\npython”)
f.close()
import io
f = open(‘test’,”w+”,15)
f.write(“mage”)
f.write(“du”)
f.write(‘hello\n’)
f.write(‘\npython’)
f.write(‘a’*(io.DEFAULT_BUFFER_SIZE – 20))
f.write(“\nwww.magedu.com/python”)
Buffering = 0
这是一种特殊的二进制模式,不要内存的buffer,可以看做是一个FIFO的文件
f = open(‘test’,”wb+”,0)
f.write(b’m’)
f.write(b’a’)
f.write(b”g”)
#f.write(b.’magedu*4′)
f.write(b’\n’)
#f.write(b.’hello\npython’)
f.close()
Buffering = -1 t和b,都是io.DEFAULT_BUFFER_SIZE
Buffering = 0 b关闭缓冲区t不支持
Buffering = 1 b就一个字节,t行缓冲,遇到换行符才flush
Buffering > 1 b模式表示行缓冲值的大小,缓冲区的值可以超过io.DEFAULT_BUFFER_SIZE直到设定的值超过后才把缓冲flus。t模式,是io.DEFAULT_BUFFER_SIZE,flush完成后吧当前字符串也写入磁盘
似乎看起来很麻烦,一般来说,只需要记得:
文本模式,一般都用默认缓冲区大小
二进制模式,是一个个字节的操作,可以指定buffer的大小
一般来说,默认缓冲区大小是个比较好的选择,除非明确知道,否则不能调整它
一般编程中,明确知道需要写磁盘了,都会手动调用榆次flush,而不是等到自动flush或者close的时候
Encoding:编码,仅文本模式使用
None表示缺省编码,依赖于操作系统,Windows,linux测试如下代码
f = open(‘test’,’w’)
f.write(‘啊’)
f.close()
Windows下缺省GBK(0xB0A1),LINUX下缺省UTF-8(0xE5 95 8A)
其他参数
Error
什么样的编码将被捕获
None和strict表示有编码错误将抛出ValueError异常:ignore表示忽略
Newline
文本模式中,换行的转换,可以转换为None,’’空子串,’\r’ , ‘\n’ , ‘\r\n’
读时。None表示’\r’ , ‘\n’ , ‘\r\n’都会被转换为’\n’:表示不会自动转换通用换行符,其他合法字符表示换行符就是指定字符,就会按照指定字符分行
写时,None表示’\n’都会被替换为系统缺省行分隔符os.linesep : ‘\n’ 或表示’\n’不替换:其他合法字符表示’\n’会被替换为指定的字符
f = open(‘test’,’w’)
f.write(‘python\rwww.python.org\nwww.magedu.com\r\npython3′)
f.close()
newline = [None,”,’\n’,’\r\n’]
for nl in newline:
f = open(‘test’,’r+’,newline=nl)
print(f.readline())
f.close()
Closefd
关闭文件描述符,True表示关闭它,False会在文件关闭后保持这个描述符。fileobj.fileno()查看
Read
Size表示读取的多少个字符的字节,负数或者None表示读取到EOF
f = open(‘test’,’r+’,0)
f.write(“magedu”)
f.write(‘\n’)
f.write(‘马哥教育’)
f.seek(0)
f.read(7)
f.close()
f = open(‘test’,’rb+’)
f.read(7)
f.read(1)
f.close()
行读取
Readline(size = -1)
一行行读取文件内容。Size设置一次能读取行内几个字符或字节。
Readline(hint = -1)
读取所有行的列表。指定hint则返回指定的行数
f = open(‘test’)
for line in f:
print(line)
f.close()
Write(s),把子串s写入到文件中并返回字符的个数
Writeline(lines),将字符串列表写入文件
f = open(‘test’,’w+’)
lines = [‘abc’,’123\n’,’magedu’]
f.writelines(lines)
f.seek(0)
print(f.read())
f.close()
Close
Flush并关闭文件对象
文件已经关闭,再次没有任何效果
其他
Seekable()是否可seek
Readable()是否可读
Writeable()是否可写
Closed 是否已经关闭
上下文管理
问题的引出
lst = []
for _ in range(2000):
lst.append(open(‘test’))
print(len(lst))
Lsof列出打开的文件,就没有#yum install lsof
$ lsof -p 1427 | grep test | wc -l
Lsof -p 进程号
Ulimit -a 查看所有限制,其中openfile就是打开文件的次数,默认1024
for x in lst:
x.close()
1,异常处理
当出现异常的时候,拦截异常,但是因为很多代码都可能出现OSError异常,还不好判断就是因为资源限制产生的
f = open(‘test’)
try:
f.write(‘abc’)#文件只读,写入失败
finally:
f.close()#这个可以
使用它finally可以保证打开的文件可以被关闭
2. 上下文管理
一种特殊的语法,交给解释器去释放文件对象
del f
with open(‘test’) as f:
f.write(‘abc’)#文件只读写入失败
f.close()
使用with ……as 关键字
上下文的管理的语句块并不会开启新的作用域
With语句块执行完的时候,会关闭文件对象
f = open(‘test’)
with f:
f.write(“abc”)
f.close()
对于类似于文件对象的IO对象,一般来说都需要在不使用的时候关闭注销,释放资源
IO被打开的时候,会获取一个文件描述符,计算机的资源是有限的,所以操作系统都会做限制
练习
指定一个源文件,实现copy到目标目录。
filename1 = ‘tmp/test.txt’
filename2 = ‘tmp/test1.txt’
f = open(filename1,’w+’)
lines = [‘abc’,’123′,’namgedu’]
f.writelines(‘\n’.join(lines))
f.seek(0)
print(f.read())
f.close()
def copy(src,dest):
with open(src) as f1:
with open(dest, ‘w’) as f2:
f2.writel(f1.read())
copy(filename1,filename2)
有一个文件,对其单词进行统计,不区分大小写,并显示单词重复最多的10个单词
d = {}
with open(‘sample’,encoding=’utf-8′) as f:
for line in f:
words = line.split()
for word in map(str.lower,words)
d[word] = d.get(word,0)+1
print(sorted(d.items(),key=lambda item:item[1],reverse=True))
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/97340