2008-08-26 228 views
4

我必须开发一个应用程序来解析日志文件并将特定数据发送到服务器。它必须在Linux和Windows上运行。C++:以非独占模式打开文件

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

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

回答

3

有没有办法在一个非独占方式打开文件,

是的,使用Win32,通过各种FILE_SHARE_Xxxx标志CreateFile时。

它是跨平台吗?

不,它需要特定于平台的代码。由于恼人的后向兼容性问题(DOS应用程序,是单一任务,假设没有任何东西可以从它们下面删除一个文件,也就是说它们可以在没有任何问题的情况下fclose()然后fopen(); Win16保留这个假设使移植DOS应用程序变得更容易,Win32保留了这个假设,使得移植Win16应用程序变得更容易,而且很糟糕),Windows默认只打开文件。

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

C++没有任何这方面的概念; C++操作环境与DOS操作环境非常相似 - 没有其他应用程序同时运行,因此不需要控制文件共享。

1

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

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

1

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

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

1

如果你只是从文件中读取,我知道它可以用Windows API CreateFile来完成。只需指定FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE作为dwShareMode的输入。

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

See msdn for more info on CreateFile

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

0

我会确保你不要保持文件打开。例如,如果你的应用程序崩溃,这会导致怪异的东西。 我会做什么:

  1. 摘要(读/写/翻身到一个新的文件)为一类,而当你想翻转到该类中的新安排文件关闭。 (这是最简单的方法,因为你已经有翻转代码,所以你已经到了一半了。)
  2. 如果你必须有多个读/写访问点,需要fstreams的所有功能,并且不想写完成一个包装,那么我能想到的唯一的跨平台解决方案就是在不需要它的时候总是关闭文件,并且在需要时翻阅代码尝试获取对文件的独占访问次数在放弃之前翻身。