【问题标题】:How to share file delete privilege when I opening a file by ifstream当我通过ifstream打开文件时如何共享文件删除权限
【发布时间】:2016-12-21 11:42:52
【问题描述】:

我想制作ifstream打开时可以删除的文件。

我知道使用 Windows API 很容易:CreateFile

CreateFile(...,FILE_SHARE_DELETE,...)

但是当我通过 ifstream 打开文件进行测试时。

打开后无法删除。

我没有在ifstream 上找到任何关于设置属性的文档,例如FILE_SHARE_DELETE

我应该如何解决这个问题?

【问题讨论】:

  • 你不能以便携的方式。
  • 如果需要,我想我会想办法用现有的 C FILE 句柄或文件号打开 ifstream,这反过来又对应于 API 级别的句柄。也许
  • 一些编译器(例如GCC)以Technical Specification 的形式提供即将成为标准的文件系统 库。您可以使用:std::experimental::filesystem::remove。否则boost 中存在相同(或相似)的库。
  • @Galik 这与FILE_SHARE_DELETE无关
  • 关于 Alf 的建议,另见stackoverflow.com/questions/475853/…

标签: c++ windows file winapi


【解决方案1】:

Visual Studio 的std::ifstream 版本有一个非标准构造函数和一个非标准open() 重载,它们都有一个额外的可选_Prot 参数用于指定“文件保护/共享标志”(请参阅​​_fsopen()可用标志的列表)。但是,delete 共享不是受支持的标志之一。

不过,还有另一种选择。 Visual Studio 的std::ifstreamstd::ofstream 版本具有接受FILE* 用于文件访问的非标准构造函数。例如,您可以使用 Microsoft 的 _open_osfhandle()_fdopen() 函数将 HANDLECreateFile() 包装到 FILE* 中(为简洁起见,删除了错误处理):

Can I use CreateFile, but force the handle into a std::ofstream?

HANDLE file_handle = CreateFile(...,FILE_SHARE_DELETE,...);
int file_descriptor = _open_osfhandle((intptr_t)file_handle, _O_RDONLY);
FILE* file = _fdopen(file_descriptor, "r");
std::ifstream stream(file);
...
// Closes stream, file, file_descriptor, and file_handle.
stream.close();

如果您需要更便于非 Microsoft 编译器的东西,您可能不得不编写一个自定义的 std::basic_streambuf 类(或者可能从 std::filebuf 派生)来包装您的 HANDLE,然后传递一个对象将该类直接传递给std::basic_istream 构造函数。

【讨论】:

  • 这个比公认的答案简单易行
【解决方案2】:

文件权限因操作系统而异:

用于读取、写入或删除的整个文件访问共享

对父目录的写+执行权限。文件本身的权限无关

由于 Windows 确实是唯一具有删除访问权限的系统,并且它已经以 CreateFile with FILE_SHARE_DELETE 的形式提供了自己的访问器,因此确实没有将这个功能标准化的动机。

如果此功能对您的程序至关重要,您可以实现此跨平台功能(请注意,根据文件大小,这可能非常昂贵):

  1. 使用fstream 打开文件进行读写;如果此操作失败,则其他文件会锁定文件,并且无法将其打开以进行删除
  2. Slurp the file
  3. close文件
  4. remove文件;如果失败,您没有文件的删除权限
  5. 使用ofstream 重新打开文件进行写入
  6. "Unslurp" the file 进入ofstream
  7. 返回ofstream

只要返回的ofstream 处于打开状态,操作系统就负责防止更改文件或其包含的目录的权限。因此,由于您已经删除了文件,因此您知道在关闭ofstream 时仍然可以删除该文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 2021-02-28
    • 2018-10-21
    • 1970-01-01
    相关资源
    最近更新 更多