概述
文件操作符
文件是操作系统的一个重要概念。所有执行I/O操作的系统调用都以文件描述符,一个非负整数,来指代打开的文件。可以用来表示所有类型的已打开文件(pipe,FIFO,socket,终端,设备,普通文件),针对每个进程,文件描述符自成一套。
一般大多数程序都使用三种标准的文件描述符。包括shell。
标准文件描述符
文件描述符 | 用途 | POSIX名称 | stdio流 |
0 | 标准输入 | STDIN_FILENO | stdin |
1 | 标准输出 | STDOUT_FILENO | stdout |
2 | 标准错误 | STDERR_FILENO | stderr |
执行文件I/O操作的4个主要系统调用:
- fd = open(pathname,flags,mode) 打开pathname所标识的文件,并返回文件描述符,用以在后面的程序中表示打开的文件。如果文件不存在,则可以设置flags位来决定是否创建新文件,flags还可以确定以什么模式打开文件(只读,只写,读写)。如果文件是新创建的,则可以设置mode参数决定文件的访问模式。如果没有创建新文件,可以忽略mode 参数。
- numread = read(fd,buffer,count) 调用从fd所指代的打开文件,从中读取最多count字节的数据,存至buffer中。read返回实际读取的字节数给numread。实际上,若在一次读取中遇到文件结束符EOF,返回值不等于count。
- numwritten = write(fd,buffer,count) 向fd所指代的文件中写入至多count字节,这些字节来自于buffer中。write返回实际写入的字节数。
- status = close(fd) 在对文件的操作都结束后,调用close(),释放文件描述符以及与之相关的内核资源。与文件相关的内核资源可自行百度操作系统相关知识。
使用以上系统调用可以简单实现一个copy程序,该程序从命令行读取两个参数(源文件path,新文件path),copy一个文件。
程序清单如下:
1 /* copy.c 2 3 Copy the file named argv[1] to a new file named in argv[2]. 4 */ 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 #ifndef BUF_SIZE /* Allow "cc -D" to override definition */ 11 #define BUF_SIZE 1024 12 #endif 13 14 int 15 main(int argc, char *argv[]) 16 { 17 int inputFd, outputFd, openFlags; 18 mode_t filePerms; 19 ssize_t numRead; 20 char buf[BUF_SIZE]; 21 22 /* Open input and output files */ 23 24 inputFd = open(argv[1], O_RDONLY); 25 if (inputFd == -1) { 26 printf("openning file %s failture", argv[1]); 27 exit(EXIT_FAILURE); 28 } 29 30 openFlags = O_CREAT | O_WRONLY | O_TRUNC; 31 filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | 32 S_IROTH | S_IWOTH; /* rw-rw-rw- */ 33 outputFd = open(argv[2], openFlags, filePerms); 34 if (outputFd == -1) { 35 printf("openning file %s failture", argv[2]); 36 exit(EXIT_FAILURE); 37 } 38 39 /* Transfer data until we encounter end of input or an error */ 40 41 while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) 42 if (write(outputFd, buf, numRead) != numRead) { 43 printf("Can not write whole file!"); 44 exit(EXIT_FAILURE); 45 } 46 47 if (numRead == -1) { 48 printf("Read failure!"); 49 exit(EXIT_FAILURE); 50 } 51 52 if (close(inputFd) == -1) { 53 printf("close file error!"); 54 exit(EXIT_FAILURE); 55 } 56 if (close(outputFd) == -1) { 57 printf("close file error!"); 58 exit(EXIT_FAILURE); 59 } 60 exit(EXIT_SUCCESS); 61 }
通用I/O
UNIX I/O模型的显著特点是其输入/输出的通用性概念。这意味着使用上面4个系统调用可以对所有类型的文件执行I/O操作,包括终端之类的设备,因此,仅使用这些系统调用编写的程序将对任何类型的文件有效。
I/O调用详解
open:打开文件
函数原型:int open (const char *pathname, int flags, .../* mode_t mode */)
返回值
调用成功:返回fd文件描述符
调用失败:返回-1 ,置errno为相应的错误标志
pathname
pathname标识要打开的文件, 如果pathname是符号链接,则会自动对其进行解引用。
flags
flags为位掩码,用于指定文件访问模式,常用的如下
O_RDONLY 以只读方式打开
O_WRONLY 以只写方式打开
O_RDWR 以读写方式打开
三种里每次只可以以一种方式打开
其它一些重要的模式:
O_CREATE 如果文件不存在,则创建空文件,一般这种情况下需要提供mode参数,不然新文件的权限将是栈中的随机值
时间: 2024-10-31 13:33:29