C ++:以非独占模式打开文件

时间:2008-08-26 10:24:11

标签: c++ windows linux filesystems

我必须开发一个解析日志文件并将特定数据发送到服务器的应用程序。它必须在Linux和Windows上运行。

当我想测试日志滚动系统(将.1添加到创建具有相同名称的新名称的名称)时,会出现问题。在Windows上(尚未在Linux上测试)我无法重命名我用std :: ifstream()(独占访问?)打开的文件,即使我在“输入模式”(ios :: in)中打开它

是否存在以非独占方式打开文件的跨平台方式?

5 个答案:

答案 0 :(得分:3)

  

有没有办法以非独占的方式打开文件,

是的,使用Win32,将各种FILE_SHARE_Xxxx标志传递给CreateFile。

  

是跨平台吗?

不,它需要特定于平台的代码。

由于恼人的向后兼容性问题(DOS应用程序,单任务,假设没有任何东西可以删除它们下面的文件,即它们可以fclose()然后fopen()没有任何问题; Win16保留了这个假设使DOS应用程序移植更容易,Win32保留了这个假设,使移植Win16应用程序更容易,而且很糟糕),Windows默认只打开文件。

底层操作系统基础设施支持删除/重命名打开的文件(虽然我认为它确实存在无法删除内存映射文件的限制,我认为这不是对* nix的限制),而是默认的开放语义不要。

C ++没有任何概念; C ++操作环境与DOS操作环境大致相同 - 没有其他应用程序同时运行,因此无需控制文件共享。

答案 1 :(得分:1)

这不是读取操作需要独占模式,而是重命名,因为这与将文件移动到新位置基本相同。

我不确定,但我认为不能这样做。请尝试复制文件,稍后在不再读取时删除/替换旧文件。

答案 2 :(得分:1)

Win32文件系统语义要求您在重命名时重命名的文件(在任何模式下)都不会打开。您需要关闭该文件,重命名该文件,然后创建新的日志文件。

Unix文件系统语义允许您重命名一个打开的文件,因为文件名只是指向inode的指针。

答案 3 :(得分:1)

如果您只是从文件中读取,我知道可以使用windows api CreateFile完成。只需指定FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE作为dwShareMode的输入。

不幸的是,这不是跨平台。但Linux可能会有类似的东西。

See msdn for more info on CreateFile

编辑:关于Greg Hewgill评论的快速说明。我刚刚测试了FILE_SHARE *的东西(也是100%肯定)。如果打开只读并指定FILE_SHARE *参数,则可以在Windows中删除和重命名文件。

答案 4 :(得分:0)

我确保你不保持文件打开。如果您的应用程序崩溃,这会导致奇怪的事情。 我要做的是:

  1. 摘要(读取/写入/滚动到新文件)到一个类中,并在您想要转到该类中的新文件时安排关闭文件。 (这是最好的方式,因为你已经有了翻转代码,你已经在那里了。)
  2. 如果您必须拥有多个读/写访问点,需要fstream的所有功能,并且不想编写完整的包装器,那么我能想到的唯一跨平台解决方案是在您不知道时始终关闭文件我需要它,并且在放弃之前需要翻转时,让翻转代码尝试获取对文件的独占访问权。