2011-05-19 19 views
6

是否可以從SplFileObject中取消鏈接文件?Unlink和SplFileObject

我沒有看到關閉底層資源的方法,並且文件句柄是私有的,因此無法擴展SplFileObject以實現該目標。

是否有任何解決方法?

+0

您可以使用'SplFileObject :: getPathName()'獲取路徑,取消設置'SplFileObject'(我假設*關閉句柄),然後'取消鏈接'你得到的路徑。 – 2011-05-20 00:08:21

+2

取消鏈接文件並不要求關閉所有文件句柄。即使文件名已被刪除,您仍然可以讀取和寫入文件。 – mario 2011-05-20 00:56:26

回答

9

我不會推薦這個,因爲PHP爲你關閉了場景背後的文件。如果你看看php的SRC,ext/spl/spl_directory.c

retval.handle = zend_objects_store_put(intern, 
    (zend_objects_store_dtor_t) zend_objects_destroy_object, 
    (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, 
    NULL TSRMLS_CC); 

處理程序是建立在爲了對付的對象清理時引用都已用盡。現在,我們檢查清理處理程序:spl_filesystem_object_free_storage

case SPL_FS_FILE: 
     if (intern->u.file.stream) { 
      if (intern->u.file.zcontext) { 
/*    zend_list_delref(Z_RESVAL_P(intern->zcontext));*/ 
      } 
      if (!intern->u.file.stream->is_persistent) { 
       php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE); 
      } else { 
       php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT); 
      } 
      if (intern->u.file.open_mode) { 
       efree(intern->u.file.open_mode); 
      } 
      if (intern->orig_path) { 
       efree(intern->orig_path); 
      } 
     } 
     spl_filesystem_file_free_line(intern TSRMLS_CC); 
     break; 

php_stream_free通話將關閉文件流爲您服務。如果您取消鏈接文件,我無法保證PHP將如何處理嘗試關閉剛剛鏈接的文件句柄。

你必須記住什麼SplFileObject爲您提供:

SplFileObject extends SplFileInfo implements RecursiveIterator , Traversable , Iterator , SeekableIterator { 

它提供了許多基於迭代器接口的文件。如果你unlink文件,它應該迭代什麼?您會注意到close()也不存在於可用的方法中。如果你想做你正在說的話,那麼你最好把文件當作資源來處理,在那裏你可以使用close()這個句柄,並使它可以與unlink()一起使用,從而避免討厭的副作用。