python的写入操作及写入缓存

最近在工作中遇到一个以前没注意的问题,卡了挺长时间没搞明白,这里记一下

首先解释一下问题:由于需求,我需要先在文件中记录一行本次实验的参数设置也就是foo中第一次的写入操作,然后在同样参数下,依次记录十次实验结果,也就是sample中的写入操作,本来正常的写入情况是先有参数设置,然后是实验的记录结果,结果在文件中发现是先写入实验结果,然后再写入参数设置,如下面展示的一样。

这个本来不太重要,毕竟都写进文件了,但是让我很难受,所以就找为什么会出现这个问题,终于还让我找到了,原因在于写操作不是你用write方法后就写入了文件,而是写在了缓存区。

看下面的实验, 在win10,通过cmd本地来写一个文件,写入字符 ff , 会返回一个2 这个是返回的字符长度,这个时候会在该执行路径下生成一个文件,我们打开这个文件发现并没有实际写入,文件里面是空的!!!

那么我们接着往里面写,发现还是空的

那么我们重新写个文件来试试,此时会发现文件中真的写入10000行ff。

这是因为Python写入过程中往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入,当你写入的字节大于或等于缓冲区的大小,就会自动写入到文件中,而当你写入的字节小于缓冲区的大小,就会一直存在缓冲区中。

解决这种问题的方法就是调用close()方法,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。

回到原来的问题,就是先执行foo方法的写入语句,此时是写入缓存了,然后内部又打开了该文件,写入实验数据后with操作结束,此时关闭了一次文件,故而先写入实验数据,此时返回foo方法,然后结束with操作,相当于关闭了文件,将缓存中的结果写入文件,使得参数的信息在实验结果后面。

解决方法就是代码中注释的部分,在写入完成后我们手动关闭一下就可以了。

With的工作原理

有一些任务如1、文件操作。2、进程线程之间互斥对象。3、支持上下文其他对象,可能事先需要设置,事后做清理工作。

由于open打开文件操作必须我们时刻记得写入完成后close文件,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。 所以python更推荐我们使用with语法来处理文件。

如果不用with语句,文件操作的代码如下:

file =open("/tmp/foo.txt")

data =file.read()

file.close()

这里有两个问题:

一是可能忘记关闭文件句柄; 

二是文件读取数据发生异常,没有进行任何处理。

下面是处理异常的加强版本:

try:

    f = open('../dataconfig/test.json', 'r')

    print(f.read())

finally:

    if f:

        f.close()

上面这个写的很冗长,使用python推荐的with如下:with还可以很好的处理上下文环境产生的异常。

with open("/tmp/foo.txt") as file:

    data=file.read()

执行with这个结构之后。f会自动关闭。相当于自带了一个finally。但是with本身并没有异常捕获的功能,但是如果发生了运行时异常,它照样可以关闭文件释放资源。

你可能感兴趣的:(python的写入操作及写入缓存)