跳转到内容

C 编程/POSIX 参考/unistd.h/open

来自维基教科书,开放的书籍,开放的世界

对于大多数文件系统,程序通过open 系统调用初始化对文件文件系统中的访问。这会分配与文件相关的资源(文件描述符),并返回一个句柄,该进程将使用该句柄来引用该文件。在某些情况下,第一次访问时会执行 open 操作。

同一个文件可以被多个进程同时打开,甚至可以被同一个进程打开(导致同一个文件有多个文件描述符),具体取决于文件组织和文件系统。对描述符的操作(例如移动文件指针或关闭它)是独立的(它们不影响同一个文件的其他描述符)。文件操作(例如写入)可以被对其他描述符的操作看到(后面的读取可以读取写入的数据)。

在打开期间,文件系统可能会为缓冲区分配内存(或者它可能等到第一次操作)。

解析绝对文件名。这可能包括连接到远程主机并通知操作员需要可移动介质。它可能包括通信设备的初始化。如果主机或介质不可用,则可能返回错误。执行对文件系统中目录的至少第一次访问。如果路径的更高级组件(目录)找不到或无法访问,通常会返回错误。如果预期文件存在但不存在,或者预期文件不存在但存在,则会返回错误。

如果预期文件存在并且存在,则根据文件元数据或访问控制列表中的权限标志限制,验证文件访问是否与请求的操作类型一致。这通常需要额外的文件系统访问,尽管在某些文件系统中元标志可能是目录结构的一部分。

如果正在创建文件,文件系统可能会根据文件系统功能分配默认的初始存储量或指定数量。如果失败,将返回错误。更新目录以包含新条目可能会执行,也可能会延迟到执行close

在打开期间可能发生的各种其他错误包括目录更新失败、不允许的多个连接、介质故障、通信链路故障和设备故障。

必须始终检查返回值并采取特定于错误的操作。

在许多情况下,特定于编程语言的运行时库打开可能会执行其他操作,包括初始化与文件相关的运行时库结构。

一旦不再需要文件,程序应该close它。这将导致运行时库和文件系统缓冲区更新到物理介质,并允许其他进程访问数据(如果需要独占使用)。一些运行时库可能会close程序调用运行时退出时打开的文件。一些文件系统可能会在程序终止时执行必要的操作。如果发生内核或电源故障,这两种情况都不太可能发生。这会导致损坏的文件系统结构,需要运行特权且耗时的文件系统实用程序,在此期间整个文件系统可能不可访问。

open 调用参数

[edit | edit source]
  1. 文件的路径名
  2. 请求对文件的访问类型(读取、写入、追加等),
  3. 使用名为 mode 的第三个参数请求初始文件权限。此参数仅在创建新文件时相关。

使用文件后,进程应该使用close调用关闭文件,该调用接受要关闭的文件的文件描述符。一些文件系统包括允许释放文件的处置。

一些计算机语言包括运行时库,其中包括针对特定文件系统的附加功能。open(或某些辅助例程)可能包括密钥大小、记录大小、连接速度的规范。一些 open 例程包括在发生错误时要执行的程序代码的规范。

perl 语言形式

[edit | edit source]
open FILEHANDLE,MODE[,EXPR]

例如

  open(my $fh, ">", "output.txt") 

Perl 还使用 Tie::File 模块的 tie 函数将数组与文件关联。[1] tie::AnyDBM_File 函数将哈希与文件关联。[2]

C 库 POSIX 定义

[edit | edit source]

open 调用由POSIX 规范标准化

int open (const char *path, int oflag, .../*,mode_t mode */);
int openat ...
int creat(const char *path, mode_t mode) 
FILE *fopen(const char *restrict filename, const char *restrict mode);

返回的值是文件描述符,它是对进程特定结构的引用,该结构包含(除其他事项外)一个位置指针,该指针指示文件中的哪个位置将被下一个操作操作。

Open 可能返回-1,指示失败,errno 详细说明错误。

文件系统还更新所有打开文件的全局表,该表用于确定文件当前是否被任何进程使用。

要打开的文件的名称。它包括文件路径,定义文件在哪个文件系统中找到(或应该创建)。

openat 期望相对路径。

oflag
[edit | edit source]

此参数通过按位或可选参数和(来自 <fcntl.h>)以下之一来形成

O_RDONLYO_RDWR

可选参数包括

O_APPEND 写入的数据将追加到文件的末尾。文件操作将始终将位置指针调整到文件的末尾。
O_CREAT 如果文件不存在,则创建它;否则,打开操作将失败,并将errno 设置为 ENOENT。
O_EXCLO_CREAT 一起使用,如果文件已存在,则失败,并将 errno 设置为 EEXIST。
O_TRUNC 如果文件已存在,则丢弃其先前内容,将其缩减为空文件。不适用于设备或命名管道。

其他标志和错误在open 调用中定义。

creat() 实现为

 int creat(const char *path, mode_t mode)
   { return open(path, O_WRONLY|O_CREAT|O_TRUNC, mode); }


fopen 使用字符串标志,例如 rwa+,并返回一个与 fgetsfputsfclose 一起使用的文件指针。

mode_t
[edit | edit source]

仅在创建新文件时可选且相关,定义 文件权限。这些包括所有者、组或所有用户对文件的读、写或执行权限。模式由调用进程的 umask 掩盖:umask 中设置的位将在模式中被清除。

另请参阅

[edit | edit source]

注意

[edit | edit source]
  1. "Tie::File". perldoc.perl.org. Retrieved 2011-08-07.
  2. "AnyDBM_File". perldoc.perl.org. Retrieved 2011-08-07.

参考文献

[edit | edit source]
华夏公益教科书