取消链接和SplFileObject

6

如何从SplFileObject中取消关联一个文件?

我没有看到关闭底层资源的方法,而且文件句柄是私有的,因此无法通过继承SplFileObject来实现该目标。

是否有任何解决办法?


您可以使用 SplFileObject::getPathName() 获取路径,然后取消设置 SplFileObject(我假设这会关闭句柄),然后删除您获取的路径。 - El Yobo
2
取消链接文件并不需要关闭所有文件句柄。即使文件名已被删除,您仍然可以很好地读写文件。 - mario
1个回答

11

我不建议这样做,因为PHP会在幕后自动关闭文件。如果您查看php源代码中的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()。如果您想要做您所说的事情,那么最好将文件视为资源处理,您可以关闭句柄并使其可用于 unlink(),以避免产生令人讨厌的副作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接