shelve保存的文件怎么无法减小?

shelve保存的文件怎么无法减小?

最近使用shelve时,发现保存的文件大小只会增大不会减小,将里面的内容使用del方法或者POP方法全部清理也不行,不知为什么,请高手指点!
示例如下:
>>> import shelve
>>> sf=shelve.open(r'f:\abc.db')
>>> for i in range(10000):
...         sf[str(i)]=i
...        
>>> sf.clear()
>>> sf.sync()
>>> sf.close()
>>> sf=shelve.open(r'f:\abc.db')
>>> sf
{}
再去查看'f:\abc.db'文件,312K,搞不明白内容都空了,文件怎么没有减小?
请高手指点,谢谢先!
新人,没用过这东西。不过多学了一个shelve这个Persistence ,看来python自带的文档还是要多看看。
try zshelve
13.4.1 Restrictions

    * The choice of which database package will be used (such as dbm, gdbm or bsddb) depends on which interface is available. Therefore it is not safe to open the database directly using dbm. The database is also (unfortunately) subject to the limitations of dbm, if it is used -- this means that (the pickled representation of) the objects stored in the database should be fairly small, and in rare cases key collisions may cause the database to refuse updates.

    * Depending on the implementation, closing a persistent dictionary may or may not be necessary to flush changes to disk. The __del__ method of the Shelf class calls the close method, so the programmer generally need not do this explicitly.

shelve依赖某个db,db文件大小完全有db的具体实现决定,比如在你清理数据后,db不会立即回收磁盘空间,可能为了将来继续操作提高效率。如果使用过mysql oralce等数据库,也会注意到有类似现象,删除表中所有数据,但是磁盘空间照样不变。shelve使用的都是嵌入式的db,但是思想和大型CS数据库一样。总之我们不需要考虑这类行为,db有自己的优化策略。
我是写了一个服务程序,要处理中转的大量数据,怕程序异常退出或者断电引起数据缓存的丢失使用了shelve,我反复测试了几次,文件很快就增到了几十M,不会减少,这样岂不是很快磁盘就占满了?看来要换种数据缓存磁盘的方法了,使用数据库也麻烦,又要增加维护数据库的成本


QUOTE:
原帖由 moatlzy 于 2008-9-13 21:28 发表
我是写了一个服务程序,要处理中转的大量数据,怕程序异常退出或者断电引起数据缓存的丢失使用了shelve,我反复测试了几次,文件很快就增到了几十M,不会减少,这样岂不是很快磁盘就占满了?看来要换种数据缓存磁 ...

shelve选择的几个db都不会减小数据库文件,唯一的方法是重新建立shelve
其实很难有完美的方案,还是找最切合实际的吧。比如你中转的滞留数据上限大概是多少?如果最多也就是几百MB,作为一个数据服务程序还能接收吧,尤其这些空间是新增数据提升性能的关键,不仅仅是占用空间而已。如果有几GB的波动且硬盘空间很紧张,就要考虑其它替代方案了。
感谢您的指点!我的中转数据不大,目前是这样处理的:一个线程用于写入shelve文件,一个线程用于取这个shelve文件里的数据进行处理,处理一条就del一条。现在的问题是这个文件只会增大(好象只写入磁盘文件,清理一条后磁盘文件实际不会清理掉),这样时间稍长些,磁盘空间就都浪费掉了。我想这样明显的问题PYTHON应该有解决方法的吧?
没用过这东西。


QUOTE:
原帖由 moatlzy 于 2008-9-14 00:37 发表
感谢您的指点!我的中转数据不大,目前是这样处理的:一个线程用于写入shelve文件,一个线程用于取这个shelve文件里的数据进行处理,处理一条就del一条。现在的问题是这个文件只会增大(好象只写入磁盘文件,清 ...

首先,这不是Python的问题或BUG,而是Feature
其次,再强调一次:那些空间不是浪费了,而是会被再次利用
再次,Python的shelve没提供shrink的方法,不是那些人不懂,而是没必要。Oracle MySQL等也有shrink的操作,都是DBA确认该表一定不会使用如此大的空间时才会做,根本没有程序自动shrink数据库的表占用空间。
最后,如果你十分在乎每条删除数据都应该释放硬盘空间,就直接调用gdbm存数据,可以reoragnize缩小空间占用,当然代价就是性能极度低下,注意不是一般的“低”,而是“极度”

再次感谢硬大侠的指点,我明白了,也学习到了新的知识,非常感谢!