需求:
将文件内容写入到硬件设备时,使用系统调用,这类I/O操作赶时间很长,为了减少I/O操作的次数,文件通常使用缓冲区(有足够多的数据才进行系统调用),文件的缓冲行为,分为全缓冲,行缓冲,无缓冲。
如何设置python中文件对象的缓冲行为?
思路:
1、全缓冲:open函数的buffering设置为大于1的整数n,n为缓冲区的大小
2、行缓冲:Open函数的buffering设置为1
3、无缓冲:open函数的buffering设置为0
代码:
# 以只写的方式打开一个文件,若不存在这个文件则新建一个文件
f = open('demo.txt','w')
# 写入三个字节
f.write('acb')
# 用tail -f来监控demo.txt的情况:
tail -f demo.txt
# 一个块一般为4096个字节,再写入4093个字节,tailf查看还是没有输出
f.write('+'*4093)
# 再写入一个字节,tail -f查看有输出了
f.write('-')
# 设置全缓冲区的大小
# 打开一个文件,设置缓冲区的大小为2048
f = open('demo2.txt','w',buffering=2048)
# 测试方法同上
# 设置行缓冲,有
即可以写入
f = open('demo3.txt','w',buffering=1)
f.write('abcd') # tailf查看文件没有内容
f.write('1234') # tailf查看文件没有内容
f.write('
') # tailf查看文件有内容:abcd1234
f.write('xyz
') # tailf查看文件有内容:xyz
# 设置无缓冲
# python3中文本不支持无缓冲,报错ValueError: can't have unbuffered text I/O
# python2中可以
f = open('demo4.txt','w',buffering=0)
f.write('a') # tailf可以立刻查看到文件中有内容出现
==========================================================================
>>> f = open('a.bin','wb')
>>> f.write(b'abc')
3
>>> f.write(b'efg')
3
>>> import io
>>> io.DEFAULT_BUFFER_SIZE
8192
>>> f.write(b'+' * (4096-6))
4090
>>> f.write(b'-')
1
>>> f.write(b'*' * 4095)
4095
>>> f.write(b'/')
1
>>> f2 = open('a.txt','w')
>>> 'a'.encode()
b'a'
>>> '齐'.encode() # 汉字对应三个字节
b'xe9xbdx90'
>>> f2.write('a' * 4095)
4095
>>> f2.write('bc')
2
>>> f2.write('+' * 999)
999
>>> f
<_io.BufferedWriter name='a.bin'>
>>> f2
<_io.TextIOWrapper name='a.txt' mode='w' encoding='UTF-8'> # 文本文件第一层为textio,缓存区的大小为8092
>>> f2.buffer # 第二层为buffer,缓存区的大小 为4096
<_io.BufferedWriter name='a.txt'>
>>> f.raw # 第三层为raw,直接对raw写操作,可以直接写入磁盘,不经过缓存区
<_io.FileIO name='a.bin' mode='wb' closefd=True>
>>> f2.raw
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-149-8eb3a70ad9d7> in <module>
----> 1 f2.raw
AttributeError: '_io.TextIOWrapper' object has no attribute 'raw'
>>> f2.buffer.raw
<_io.FileIO name='a.txt' mode='wb' closefd=True>
>>> f2.write('*' * (8192-5096))
3096
>>> f2.write('-')
1
>>> f3 = open('/dev/pts/2','w') # 这个tty对应的文件是一个行缓冲文件
>>> f3.isatty()
True
>>> f3.write('abc')
3
>>> f3.write('cfg')
3
>>> f3.write('
') # 输入了
才会写入磁盘
1
>>> f = open('a.bin','wb',buffering=8192) # 设定全缓冲,缓冲区的大小
>>> f.write(b'+' * 4097)
4097
>>> f.write(b'-' * 4097)
4097
>>> f.raw.write(b'abc')
3
>>> f.raw.write(b'abc')
3
>>> f = open('a.bin','wb',buffering=0) # 设定全缓冲不进行缓冲
>>> f = open('a.bin','wb',buffering=0)
>>> f.write(b'abc')
3
>>> f2 = open('a.txt','w',buffering=1) # 文件文件设定行缓冲,二进制文件不可以设定行缓冲
>>> f2.write('abc')
3
>>> f2.write('efg)
File "<ipython-input-168-bc2a1864731e>", line 1
f2.write('efg)
^
SyntaxError: EOL while scanning string literal
>>> f2.write('efg')
3
>>> f2.write('
')
1
>>>