2011-04-04 17 views
1

我正在設計一個具有撤銷/重做功能的類,並且必須臨時存儲大量數據。我目前正在實現一個「臨時」文件,通過重載運行時的文件來刪除該文件,但我不得不相信有更好的方法來做到這一點。我嘗試過使用tempfile模塊,但它不起作用,因爲擱置模塊需要一個名稱,而不是文件對象(grr)。臨時貨架?

無論如何,想知道是否有人有更好的方法來做到這一點。代碼的重要部分如下。

import os, shelve 
from time import time 
class DataHandlerUser(DataHandler): 
    def __init__(self, data): 
     # storing items 
     self.__unredofilename = os.path.dirname(__file__) + '/.undoredo' + str(time()) + '.pyworkbooks' 
     try: 
     os.remove(self.__unredofilename) 
     except OSError: pass 

     self._undoredoBuffer = shelve.open(self.__unredofilename) 
     # ... rest of init 


    def __del__(self): 
     # simple check to make sure not tampered with 
     if '.undoredo' not in self.__unredofilename or '.pyworkbooks' not in self.__unredofilename: 
     raise Exception('Critical Error: Internal filename for undo/redo operations tampered with') 
     try: 
     os.remove(self.__unredofilename) 
     except OSError: pass 

回答

4

根據你的代碼是如何運行你仍然可能遇到的競爭條件,其中兩種不同的工藝獲得相同的時間戳和相同的文件名,罕見的,因爲這可能是。添加當前的進程ID將有助於緩解這一點,但我建議您堅持使用tempfile模塊。

如果你只需要臨時文件的名稱,您可以使用tempfile.mkstemp和使用文件名之前關閉了返回的文件描述符:

import os, tempfile 
fd, self._undo_fname = tempfile.mkstemp(suffix='.undoredo', dir='/tmp') 
os.close(fd) 
self._undo_buffer = shelve.open(self._undo_fname) 
+0

謝謝,這是我應該怎麼做文件名偉大的答案。你覺得我怎麼擺脫臨時文件?我在想,應該有更好的方式,但也許不會。我喜歡使用'/ tmp'目錄的想法,出於某種原因,我認爲你需要成爲root才能到達那裏! (我對linux很陌生,並且覺得主目錄下面的所有內容都是root)。感謝您讓我知道這寶石的信息! – 2011-04-05 00:28:05

+0

不客氣,很高興我能幫上忙。您可以省略__dir ='/ tmp'__參數,它將使用操作系統的默認臨時目錄(在Unix上恰好是__/tmp__),這是更好的跨平臺行爲。我認爲在這種情況下使用'__del__'是可以的,因爲擱架的使用壽命與__DataHandler__有關。在刪除擱置文件名之前,您可能還想調用'self._undoredoBuffer.close()'。 – samplebias 2011-04-05 00:39:38

+1

這會導致一個錯誤'db type could not be determined'。在關閉它之前,你應該在文件中存儲一個空的數據庫 – 2011-04-05 02:00:06

2

貨架使用anydbm檢測所使用的數據庫的類型在文件中。

你可以在那裏創建mkstemp()一個臨時文件,並把一個空bsddb(或任何你喜歡),然後通過該文件名擱置