最近在维护一个老项目时发现,该程序的日志在程序运行时是不能够被其他程序打开的,也就不能通过日志实时地观察程序的运行状态。在我的印象里,我一直认为打开的文件都是共享的,这应该是个错觉。本篇日志主要总结了在打开一个文件时所使用函数接口,方便以后查阅。

fopen

fopen 应该是最普通也是最常见的文件操作接口了,属于标准C接口,其完整形式如下。

FILE* fopen(const char* filename,
	    const char* mode);

使用该接口创建的日志文件是可以在程序运行时被其他文本浏览器打开的,也就是说该文件是以共享的方式打开的。

fopen_s

fopen_s 较前一个接口提升了安全性,是C11标准中的接口,其完整形式如下。

errno_t fopen_s(FILE *restrict *restrict streamptr,
		const char *restrict filename,
		const char *restrict mode);

使用该接口创建的日志文件不可以在程序运行时被其他文本浏览其打开,该文件接口以独占方式方式打开文件。

_fsopen

_fsopen 是windows平台专属的接口,可以在打开文件时指定共享权限,其完整形式如下。

FILE *_fsopen(const char *filename,
	      const char *mode,
	      int shflag);

其中的 shflag 可取的值有以下几种。
_SH_COMPAT Sets Compatibility mode for 16-bit applications.
_SH_DENYNO Permits read and write access.
_SH_DENYRD Denies read access to the file.
_SH_DENYRW Denies read and write access to the file.
_SH_DENYWR Denies write access to the file.

使用该接口创建文件时可以限定其他程序在访问时的共享权限。

这个函数还有一个 wchar_t 版本的接口,形式为 _wfsopen

fstream

上面介绍的几种接口都是C风格的,而 std::fstream 是C++风格的接口,其完整形式如下。

// constructor
explicit basic_fstream( const char* filename,
	       std::ios_base::openmode mode = ios_base::in|ios_base::out );

fstream 是面向对象风格的接口,在使用时创建一个文件流对象,该对象可以接受流定向符号的输出和输出,拓展起来更加灵活。