跳到内容

C 语言入门/C 系统调用文件 I/O

来自维基教科书,自由的教科书

通过系统调用进行文件 I/O 比调用 C 文件 I/O 库更简单,并且在更低的级别上运行。有七个基本的文件 I/O 系统调用

   creat()     Create a file for reading or writing.
   open()      Open a file for reading or writing.
   close()     Close a file after reading or writing.
   unlink()    Delete a file.

   write()     Write bytes to file.
   read()      Read bytes from file.

这些调用是为 UNIX 操作系统设计的,不是 ANSI C 规范的一部分。

使用这些系统调用需要一个名为 "fcntl.h" 的头文件

   #include <fcntl.h>

"creat()" 系统调用,当然,会创建一个文件。它有以下语法

   <file descriptor variable> = creat( <filename>, <protection bits> );

此系统调用返回一个整数,称为 "文件描述符",它是一个标识由 "creat()" 生成的文件的数字。此数字被程序中的其他系统调用用来访问文件。如果 "creat()" 调用遇到错误,它将返回文件描述符值为 -1。

"文件名" 参数给出新文件的所需文件名。 "权限位" 给出文件的 "访问权限"。文件有三个

"权限" 与之相关

  • 写入权限
  Allows data to be written to the file.
  • 读取权限
  Allows data to be read from the file.
  • 执行权限
  Designates that the file is a program that can be run.

这些权限可以为三个不同的级别设置

  • 用户级别
  Permissions apply to individual user.
  • 组级别
  Permissions apply to members of user's defined "group".
  • 系统级别
  Permissions apply to everyone on the system.

对于 "creat()" 系统调用,权限以八进制表示,其中八进制数字为每个权限级别的三个权限位给出权限。在八进制中,权限设置

   0644

—授予用户读取和写入权限,但仅授予

组和系统读取权限。以下八进制数字授予每个人所有权限

   0777

尝试 "creat()" 一个现有文件(程序对该文件具有写入权限)不会返回错误。它将改为擦除文件的内容并返回该文件的描述符。

例如,要创建一个名为 "data" 的文件,该文件对系统上的每个人都具有读取和写入权限,需要以下语句

   #define RD_WR 0666
   ...
   int fd;                               /Define file descriptor. */
   fd = creat( "data", RD_WR );

"open()" 系统调用打开一个现有文件以供读取或写入。它有以下语法

   <file descriptor variable> = open( <filename>, <access mode> );

"open()" 调用与 "creat()" 调用类似,因为它返回给定文件的描述符,并在遇到错误时返回描述符 -1。但是,第二个参数是 "访问模式",而不是权限代码。有三种模式(在 "fcntl.h" 头文件中定义)

   O_RDONLY    Open for reading only.
   O_WRONLY    Open for writing only.
   O_RDWR      Open for reading and writing.

例如,要打开 "data" 以供写入,假设该文件是由另一个程序创建的,将使用以下语句

   int fd;
   fd = open( "data", O_WRONLY );

在继续之前,还要补充几点

  • "creat()" 调用隐含 "open()"。无需 "creat()" 一个文件,然后 "open()" 它。
  • 操作系统有一个对程序在任何时候可以打开的文件数量的限制。
  • 文件描述符不过是一个任意数字,程序使用它来区分一个打开的文件和另一个文件。当文件关闭时,重新打开它可能不会再给它相同的描述符。

"close()" 系统调用非常简单。它所做的就是当不再需要访问文件时 "关闭" 一个打开的文件。 "close()" 系统调用有以下语法

   close( <file descriptor> );

"close()" 调用如果成功,将返回 0,如果遇到错误,将返回 -1。

"unlink()" 系统调用删除文件。它有以下语法

   unlink( <file_name_string> );

它在成功时返回 0,在失败时返回 -1。注意:即使在 unlink 后,您仍然可以使用 fd 读取/写入。

"write()" 系统调用将数据写入打开的文件。它有以下语法

   write( <file descriptor>, <buffer>, <buffer length> );

文件描述符由 "creat()" 或 "open()" 系统调用返回。 "缓冲区" 是指向包含数据的变量或数组的指针; "缓冲区长度" 给出要写入文件中的字节数。

虽然不同数据类型在不同系统上的字节长度可能不同,但可以使用 "sizeof()" 语句提供以字节为单位的正确缓冲区长度。 "write()" 调用可以指定如下

   float array[10];
   ...
   write( fd, array, sizeof( array ) );

"write()" 函数返回它实际写入的字节数。它在错误时将返回 -1。

"read()" 系统调用从打开的文件中读取数据。它的语法与 "write()" 调用完全相同

   read( <file descriptor>, <buffer>, <buffer length> );

"read()" 函数返回它实际返回的字节数。在文件末尾,它返回 0,或在错误时返回 -1。

华夏公益教科书