V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
wisefree
V2EX  ›  Python

怎么设置 python 中 open 的 buffering 参数

  •  
  •   wisefree · 2016-12-18 13:24:14 +08:00 · 5200 次点击
    这是一个创建于 2700 天前的主题,其中的信息可能已经有所发展或是发生改变。

    buffering>1

    f = open('./test.txt', 'w', buffering=1024)
    
    f.write('+'*4)
    

    打开 test.txt 发现已经有了++++,缓冲区不是设置成了 1024 么,怎么会这样

    buffering=1

    f = open('./test.txt', 'w', buffering=1)
    
    f.write('+'*4)
    

    打开 test.txt 没有++++,这种情况是符合帮助文章的描述的

    请问这是怎么回事呢?>_<

    第 1 条附言  ·  2016-12-18 14:15:18 +08:00
    尝试了两个平台
    系统: windows
    python 3.5.1

    系统: virtualbox ubuntu
    python 3.5.1
    16 条回复    2016-12-19 10:05:53 +08:00
    a87150
        1
    a87150  
       2016-12-18 14:48:22 +08:00
    以我粗浅的了解, 0 是关, 1 是开。
    wisefree
        2
    wisefree  
    OP
       2016-12-18 14:58:53 +08:00
    @a87150 不是这样的。我按照 python 帮助文档定义进行操作,没有得到预期的结果
    Kisesy
        3
    Kisesy  
       2016-12-18 15:08:44 +08:00   ❤️ 1
    f = open('./test.txt', 'w', buffering=1024)
    f.write('+'*4)
    import time
    time.sleep(10)

    这样呢,在十秒内看看里面有没有
    Kisesy
        4
    Kisesy  
       2016-12-18 15:10:11 +08:00
    额,看错问题了
    wwqgtxx
        5
    wwqgtxx  
       2016-12-18 16:13:08 +08:00 via iPhone   ❤️ 1
    如果你程序只有这几行,会在程序结束的时候自动 flush ,你如果要测试,在 write 后 sleep 很长时间,同时在程序未结束的时候查看文件
    wisefree
        6
    wisefree  
    OP
       2016-12-18 18:53:53 +08:00
    @Kisesy 10 秒内看看里面没有,就算 10s 后里面也没有, f.flush()后才有,:),谢谢!
    wisefree
        7
    wisefree  
    OP
       2016-12-18 18:55:55 +08:00
    @wwqgtxx 嗯嗯,确实如此,谢谢啦。 sleep(10), 10 秒内里面没有内容, 10s 后里面也没有, f.flush()才有++++
    为什么要自动 flush 呢?这个真心让人困惑
    mringg
        8
    mringg  
       2016-12-18 21:39:04 +08:00 via iPhone   ❤️ 1
    你用控制台尝试下,程序退出会被强制 flush 的
    wwqgtxx
        9
    wwqgtxx  
       2016-12-19 01:00:50 +08:00 via iPhone   ❤️ 1
    @wisefree 如果在程序结束还不强制 flush ,那这个 buffering 本身设计就不合理了
    而且 open 的 buffering 是由系统实现的,系统在关闭所有输入输出流之前都会强制 flush
    至于问为什么,我只能说符合大部分人的理解观念
    要是不自动 flush 会带来无尽的坑
    SlipStupig
        10
    SlipStupig  
       2016-12-19 02:21:22 +08:00   ❤️ 1
    给一个官方的解释:“ The optional buffering argument specifies the file ’ s desired buffer size: 0 means unbuffered, 1 means line buffered, any other positive value means use a buffer of (approximately) that size (in bytes). A negative buffering means to use the system default, which is usually line buffered for tty devices and fully buffered for other files. If omitted, the system default is used. ”
    1 代表启用, 0 代表关闭,为负的时候,由系统来管理,一般缓存 tty 设备上
    wisefree
        11
    wisefree  
    OP
       2016-12-19 08:18:52 +08:00
    @SlipStupig 谢啦,但是帮助文档的解释不能回答我的问题
    wisefree
        12
    wisefree  
    OP
       2016-12-19 08:25:26 +08:00
    @mringg 确实如此,谢啦!

    运行环境: virtualbox ubuntu ipython3.5.1
    我在 ipython 控制台中,打开了两个终端,我尝试了一下如下代码

    终端 1 : ipython (还未退出)
    ``` python
    f = open('test.txt', 'w', buffering=4)

    f.write('+'*4)

    f.write('+')
    ```
    终端 2
    tail -f test.txt

    但是 test.txt 没有出现+


    在终端 1 中输入 exit ,退出 ipython
    终端 2 出现了 5 个+


    通过你们的解释,这个我能理解了,程序中强制 flush

    但是程序没有退出,为什么没有进行 flush 呢?
    wisefree
        13
    wisefree  
    OP
       2016-12-19 08:26:46 +08:00
    @wwqgtxx 谢谢!现在我在终端运行代码,终端退出和未退出的情形让我有点困惑。

    运行环境: virtualbox ubuntu ipython3.5.1
    我在 ipython 控制台中,打开了两个终端,我尝试了一下如下代码

    终端 1 : ipython (还未退出)
    ``` python
    f = open('test.txt', 'w', buffering=4)

    f.write('+'*4)

    f.write('+')
    ```
    终端 2
    tail -f test.txt

    但是 test.txt 没有出现+


    在终端 1 中输入 exit ,退出 ipython
    终端 2 出现了 5 个+


    通过你们的解释,这个我能理解了,程序退出强制 flush

    但是程序没有退出,为什么没有进行 flush 呢?
    wwqgtxx
        14
    wwqgtxx  
       2016-12-19 08:51:11 +08:00 via iPhone   ❤️ 1
    @wisefree 很多系统在实现的时候缓冲区并不是只有一个,你这个最上层的缓冲区缓冲区满了填充了下层缓冲区而已。
    比如一般你 read()的缓冲区是 glibc 实现的,而系统的内核区还是有驱动级别的缓冲区,硬件本身也是有缓冲区的。而且并不能保证 python 给你返回的就是原生系统实现的 file 对象,可能是 cpython 包装了一层
    而 flush 会强制要求系统底层刷新(虽然系统到底是否执行是另一回事)
    wwqgtxx
        15
    wwqgtxx  
       2016-12-19 08:53:09 +08:00 via iPhone   ❤️ 1
    这也就是为什么文件的读写经常需要加锁,因为在多进程同时读写同一个文件的时间很容易出现这种缓存不一致的情况
    wisefree
        16
    wisefree  
    OP
       2016-12-19 10:05:53 +08:00
    @wwqgtxx 谢谢!答案太精彩了!越往下学,好像内容越来越多了,~_~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3183 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 14:07 · PVG 22:07 · LAX 07:07 · JFK 10:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.