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

C++ C++;:以非独占模式打开文件,c++,windows,linux,filesystems,C++,Windows,Linux,Filesystems,我必须开发一个解析日志文件并将特定数据发送到服务器的应用程序。它必须同时在Linux和Windows上运行 当我想要测试日志滚动系统(在日志滚动系统的名称后面附加.1,并创建一个同名的新日志滚动系统)时,就会出现这个问题。在Windows上(尚未在Linux上测试),我无法重命名使用std::ifstream()打开的文件(独占访问?),即使我以“输入模式”(ios::in)打开它 有没有跨平台的方式以非独占方式打开文件?需要独占模式的不是读取操作,而是重命名,因为这与将文件移动到新位置基本相同

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

当我想要测试日志滚动系统(在日志滚动系统的名称后面附加.1,并创建一个同名的新日志滚动系统)时,就会出现这个问题。在Windows上(尚未在Linux上测试),我无法重命名使用std::ifstream()打开的文件(独占访问?),即使我以“输入模式”(ios::in)打开它


有没有跨平台的方式以非独占方式打开文件?

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


我不确定,但我认为这是办不到的。请尝试复制该文件,然后在不再读取时删除/替换旧文件。

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


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

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

不幸的是,这不是跨平台的。但是Linux可能也有类似的情况

编辑:只是一个关于格雷格·休吉尔评论的简短说明。我刚刚用FILE_SHARE*的东西进行了测试(也要100%确定)。如果以只读方式打开并指定文件共享*参数,则可以在windows中删除和重命名文件

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

是,使用Win32,将各种文件\u共享\u Xxxx标志传递给CreateFile

是跨站台的吗

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

由于令人恼火的向后兼容性问题(DOS应用程序是单任务的,因此假定没有任何东西可以从其下删除文件,即它们可以fclose()然后fopen())没有任何问题;Win16保留了这个假设以使移植DOS应用程序更容易,Win32保留了这个假设以使移植Win16应用程序更容易,这很糟糕),Windows默认以独占方式打开文件

底层操作系统基础设施支持删除/重命名打开的文件(尽管我相信它确实有无法删除内存映射文件的限制,我认为这不是*nix上的限制),但默认打开语义不支持


C++对此没有任何概念;C++操作环境与DOS操作环境基本相同——没有其他并发运行的应用程序,所以不需要控制文件共享。例如,如果你的应用程序崩溃,这会导致一些奇怪的事情。 我要做的是:

  • 将(读取/写入/滚动到新文件)抽象到一个类中,并在您希望滚动到该类中的新文件时安排关闭该文件。(这是最整洁的方式,既然您已经有了滚动代码,那么您已经走到了一半。)
  • 如果您必须有多个读/写访问点,需要fstreams的所有功能,并且不想编写完整的包装器,那么我能想到的唯一跨平台解决方案就是在不需要时始终关闭文件,当文件需要在放弃之前进行翻滚时,让翻滚代码尝试几次以独占方式访问该文件