如何在C+中以独占模式打开文件+; 我在C++中实现了一些文件系统。到目前为止,我使用的是fstream,但我意识到不可能以独占模式打开它。由于有许多线程,我希望允许多次读取,并且当以写入模式打开文件时,我希望以独占模式打开文件? 最好的方法是什么?我认为Boost提供了一些功能。还有其他可能吗?我还想看一个简单的例子。如果在C++中做不好/好,我也可以用C编写。

如何在C+中以独占模式打开文件+; 我在C++中实现了一些文件系统。到目前为止,我使用的是fstream,但我意识到不可能以独占模式打开它。由于有许多线程,我希望允许多次读取,并且当以写入模式打开文件时,我希望以独占模式打开文件? 最好的方法是什么?我认为Boost提供了一些功能。还有其他可能吗?我还想看一个简单的例子。如果在C++中做不好/好,我也可以用C编写。,c++,io,C++,Io,我正在使用Windows。如果文件已经以写模式打开,您可以手动阻止自己打开它。只需在内部跟踪在写入模式下打开的文件 也许您可以散列文件名,并在使用写访问权限打开时将其存储在表中。这将允许快速查找以查看文件是否已打开。< P>在许多操作系统中,这是不可能的,所以C++ 不支持它。您必须编写自己的streambuf。 如果你唯一担心的平台是Windows,那么你可以 可能使用它提供的独家模式打开。 但是,更可能的情况是,您希望使用某种类型的文件 锁定,这是更精确的,并可在大多数情况下,如果没有 所有

我正在使用Windows。

如果文件已经以写模式打开,您可以手动阻止自己打开它。只需在内部跟踪在写入模式下打开的文件


也许您可以散列文件名,并在使用写访问权限打开时将其存储在表中。这将允许快速查找以查看文件是否已打开。

< P>在许多操作系统中,这是不可能的,所以C++ 不支持它。您必须编写自己的
streambuf
。 如果你唯一担心的平台是Windows,那么你可以 可能使用它提供的独家模式打开。 但是,更可能的情况是,您希望使用某种类型的文件 锁定,这是更精确的,并可在大多数情况下,如果没有 所有平台(但不是便携式),您需要
LockFileEx
在Windows下,
fcntl
在Unix下)

在Posix下,您还可以使用
pthread\u rblock
。布滕霍夫 给出了使用经典互斥和 C++11中存在的条件变量,因此 实际实现一个可移植版本(提供所有 读者和作者在Posix中处于相同的过程中 请求将跨流程边界工作,但事实并非如此
对于C++线程原语,是这样的。

< p>如果你的应用程序只在Windows上工作,那么Win32 API函数“是你的选择。
例如:HANDLE hFile=::CreateFileW(lpszFileFullPathName,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL)

您可以重命名文件,用新名称更新,然后重新命名。我已经完成了,但是有点重。

如果您愿意使用boost,那么我建议您使用file\u lock类。这意味着您希望保留打开/关闭的文件的文件名,因为fstream不为您这样做

它们有两种模式
lock()

请注意,您最终会发现,以这种方式管理读写这两者是非常复杂的。也就是说,如果总是有人阅读,共享锁可能永远不会被释放。在这种情况下,独占锁将永远不会有机会使用

// add the lock in your class
#include <boost/interprocess/sync/file_lock.hpp>
class my_files
{
...
private:
    ...
    boost::file_lock     m_lock;
};
现在您可以安全地锁定文件(即,您锁定、执行可能抛出的操作,在退出当前{}-块之前始终解锁):

请注意,为了安全起见,您应该检查指针是否确实已分配,如果未定义,则表示文件尚未打开,因此我建议您抛出:

if(m_lock)
{
    safe_exclusive_lock guard(*m_lock);
    ...do work here...
}
else
{
    throw file_not_open();
}
// here the lock was released so you cannot touch the file anymore
在“打开”中,创建锁:

bool open(std::string const & filename)
{
    m_stream.open(...);
    ...make sure it worked...
    m_lock.reset(new file_lock(filename));
    // TODO: you may want a try/catch around the m_lock and
    //       close the m_stream if it fails or use a local
    //       variable and swap() on success...
    return true;
}
不要忘记在关闭时释放锁定对象:

void close()
{
    m_lock.reset();
}

这种低级的东西最好用C语言完成,开销越小越好…@bash.d胡说八道,你为什么这么认为?C++的全部要点是提供无开销抽象。我把你钉成了一个知道的人。“KoRADRoOLPHP,我不知道你,但是我不知道C++中实现的许多文件系统…@ Bash。D抓取系统函数,把它们放在<代码> STD::StudiBuf实现。@康拉德鲁道夫,如果你没问题,提供一个合适的答案!我不确定这是否是最好的主意,因为我将不得不保留所有打开的文件。(请注意,如果一个文件A在读模式下打开,而有人想在写模式下打开它,则需要等待读模式完成)。我如何以及为什么要编写自己的streambuf?我认为对我来说,只使用这个windows api会更容易,因为在这里@SebastianCygert,windows api需要输出一个
char
缓冲区;
ostream
接口处理格式化和字符串转换。
streambuf
类是两者之间的桥梁。例如:HANDLE hFile=::CreateFileW(lpszFileFullPathName,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);您想编辑您的答案并在那里添加示例。相关
safe_exclusive_lock guard(*m_lock);
if(m_lock)
{
    safe_exclusive_lock guard(*m_lock);
    ...do work here...
}
else
{
    throw file_not_open();
}
// here the lock was released so you cannot touch the file anymore
bool open(std::string const & filename)
{
    m_stream.open(...);
    ...make sure it worked...
    m_lock.reset(new file_lock(filename));
    // TODO: you may want a try/catch around the m_lock and
    //       close the m_stream if it fails or use a local
    //       variable and swap() on success...
    return true;
}
void close()
{
    m_lock.reset();
}