apue_Linux下文件I/O系统调用

1、文件描述符

定义:

  • 文件描述符(file descriptor, fd)是Linux内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。
  • 程序在开始运行时,系统会自动打开三个文件描述符,0是标准输入,1是标准输出,2是标准错误。
  • POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号码,因此第一次打开的文件描述符一定是3。
文件描述符用途POSIX文件描述符标准I/O文件流
0标准输入STDIN_FILENOstdin
1标准输出STDOUT_FILENOstdout
2标准出错STDERR_FILENOstderr

代码演示:

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#define MSG_STR "Hello World\n"

int main(int main, char *argv[])
{
 	printf("%s", MSG_STR);
 	fputs(MSG_STR, stdout);
 	write(STDOUT_FILENO, MSG_STR, strlen(MSG_STR));
 	return 0;
}

执行结果:

Hello World
Hello World
Hello World

2、文件I\O操作函数

open() 系统调用

头文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

函数定义:

int open(const char *pathname, int flags, mode_t mode);

函数功能:

  • 用来打开一个文件。

返回值:

  • 返回一个文件描述符(file description)。

参数解析:

  • pathname:要打开的文件、设备的路径。
  • flags:由多个选项进行“或”运算构造flag参数 。
  • mode:需要创建文件时的指定文件的权限模式,如0666。
选项
必选O_RDONLY (只读)、 O_WRONLY(只写)、 O_RDWR(读写)
可选O_APPEND:每次写时都追加到文件的尾端。
O_CREAT:文件不存在则创建它,使用该选项需要第三个参数mode。
O_TRUNC:如果文件存在,而且为只写或读写成功打开,则将其长度截取为0;
O_NONBLOCK:如果path是一个FIFO、块设备、字符特殊文件则此选项为文件的本次打开和后续的I/O操作设置非阻塞模式方式(O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY… )。

代码示例:

int fd;
fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
fd = open(“text.txt”, O_WRONLY|O_APPEND);

write() 系统调用

头文件:

#include <unistd.h>

函数定义:

ssize_t write(int fd, const void *buf, size_t count);

函数功能:

  • 往打开的文件描述符fd指向的文件中写入buf指向的数据。

返回值:

  • 返回值<0则说明写入出错,返回值>0则为实际写入的数据大小。

参数解析:

  • fd:文件描述符
  • buf:指针
  • count:buf指向的要写入的数据的大小

read() 系统调用

头文件:

#include <unistd.h>

函数定义:

ssize_t read(int fd, void *buf, size_t count);

函数功能:

  • 从打开的文件描述符对应的文件中读取数据放到buf指向的内存空间中去。

返回值:

  • 返回值<0则说明写入出错,返回值>0则为实际写入的数据大小。

参数解析:

  • fd:文件描述符
  • buf:指针
  • count:buf指向的内存空间剩余的空间大小

lseek()系统调用

  • 我们在从文件里读出内容,或往文件写入内容的时候都有一个起始地址,这个起始地址就是当前文件偏移量,当我们对文件进行读写的时候都会使文件偏移量往后偏移。

头文件:

#include <sys/types.h>
#include <unistd.h>

函数定义:

off_t lseek(int fd, off_t offset, int whence);

函数功能:

  • 调整文件偏移量的地址。

参数解析:

  • fd:文件描述符
  • offset:文件偏移量的位置
  • whence:
whence位置
SEEK_SET文件头
SEEK_CUR当前位置
SEEK_END文件尾

代码示例:

lseek(fd, 0, SEEK_SET); 将文件偏移量设置到了文件开始的第一个字节上。
lseek(fd, 1, SEEK_SET); 将文件偏移量设置到了文件开始的第二个字节上。
lseek(fd, 0, SEEK_END); 将文件偏移量设置到文件的最后一个字节上。
lseek(fd, -1, SEEK_END); 将文件偏移量设置到文件的倒数第二个字节上。

dup() 和 dup2() 系统调用

头文件:

#include <unistd.h>

函数定义:

int dup(int oldfd);
int dup2(int oldfd, int newfd);

函数功能:

  • 复制一个新的文件描述符来指向fd对应的文件。这两个系统调用经常用在标准输入、标准输出、标准出错重定向。

返回值:

  • dup()返回的新文件描述符一定是当前可用文件描述符中的最小数值;
  • dup2可以用fd2参数来指定新的文件描述符。如果fd2已经打开,则先关闭。如fd等于fd2, 则dup2返回fd2, 而不关闭它。

代码演示:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv)
{
 int fd = -1;
 fd = open("std.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);
 if(fd < 0)
 {
 printf("Open file failure: %s\n", strerror(errno));
 return ;
 }
 
 dup2(fd, STDIN_FILENO); //标准输入重定向到 std.txt 文件中去
 dup2(fd, STDOUT_FILENO); //标准输出重定向到 std.txt 文件中去
 dup2(fd, STDERR_FILENO); //标准出错重定向到 std.txt 文件中去
 printf("fd=%d\n", fd);
 
 close(fd);
}

cat std.txt查看执行结果:

fd = 3

access()系统调用

函数原型:

int access(const char *path, int mode);

  • access()可以用来测试文件是否存在或测试其权限位,其中第一个参数path是相应的文件路径名,第二个参数是要测试的模式。
  • 其中mode说明如下:
模式说明
R_OK测试读许可权
W_OK测试写许可权
X_OK测试执行许可权
F_OK测试文件是否存在

返回值:

  • On success,zero is returned. On error , -1 is returned, and errno is set appropriately.

代码演示:

#include <stdio.h>
#include <unistd.h>
#define TEST_FILE "access.c"
int main(void)
{
 	if( access(TEST_FILE, F_OK)!=0 ) 
 	{
 		printf("File %s not exist!\n", TEST_FILE);
 		return 0;
 	}
 	printf("File %s exist!\n", TEST_FILE);
 	if(access(TEST_FILE, R_OK)==0)
 	printf("READ OK\n");
 	if(access(TEST_FILE, W_OK)==0) 
 	printf("WRITE OK\n");
 	if(access(TEST_FILE, X_OK)==0)
 	printf("EXEC OK\n");
	return 0;
}

执行结果:

File access.c exist!
READ OK
WRITE OK

unlink()系统调用

函数原型:

#include <unistd.h>
int unlink(const char *pathname);

  • 该系统调用可以用来删除文件,其本质是让文件的链接记数自减。调用该函数将path指定的文件的链接数减1,如果对该文件还有其他链接存在,则仍可以通过其他链接访问该文件的数据。
  • 只有当链接记数达到0时,该文件的内容才可被删除。如果有进程打开了该文件,其内容也不能被删除。关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个记数达到0,内核再去检查它的链接记数,如果记数也是0,那么就删除该文件内容。

函数返回值:

  • On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值