linux应用编程-文件操作

一、文件描述符

1.1 文件描述符本质

  1. 文件描述符的本质是一个数字,这个数字是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指针,再间接访问得到这个文件对应的文件表。
  2. 文件描述符这个数字是open系统调用内部由操作系统遵照一定的规律,自动分配的
  3. 操作系统规定,fd从0开始依次增加。fd也是有最大限制的。linux中文件描述符表是个数组(不是链表),fd是index,文件表指针是value

1.1 linux中文件描述符的分配

  1. 调用open时,内核会从文件描述符表中挑选一个最小的未被使用的数字返回。如果之前fd已经占满了0-9,那么我们下次open得到的一定是10.
  2. linux fd中0、1、2已经默认被系统占用了,因此用户进程得到的最小的fd就是3
  3. 当我们运行一个程序,得到一个进程,内部就默认已经打开了3个文件,这三个文件对应的fd就是0、1、2。
  4. 这三个文件分别叫stdin、stdout、stderr。也就是标准输入、标准输出、标准错误。

1.2 标准输入、标准输出

  1. 标准输入一般对应的是键盘(可以理解为:0这个fd对应的是键盘的设备文件)
  2. 标准输出一般是LCD显示器(可以理解为:1对应LCD的设备文件)

二、lseek

2.1 文件指针

  1. 在动态文件中,通过文件指针来表征正在操作的位置。
  2. 文件指针,就是文件管理表结构体里面的一个指针。
  3. 文件指针是vnode中的一个元素,这个指针表示当前正在操作文件流的哪个位置。
  4. 这个指针不能被直接访问,linux系统用lseek函数来访问这个文件指针。

2.2 lseek函数

lseek函数是一个API ,在linux中 用 命令 man 2查询

man 2 lseek

2.3 lseek测文件长度

int cal_len(const char *pathname)
{
	// fd 就是file descriptor,文件描述符
	int fd  = -1;
	int ret = -1;	
	// 第一步:打开文件
	fd = open(pathname, O_RDONLY);
	if (-1 == fd)// 有时候也写成: (fd < 0)
	{	
		perror("文件打开错误");
		return -1;
	}	
	// 此时文件指针指向文件开头
	// 用lseek将文件指针移动到末尾,然后返回值就是文件指针距离文件开头的偏移量,也就是文件的长度了
	ret = lseek(fd, 0, SEEK_END);	
	return ret;
}

三、dup

3.1 dup进行描述符复制

  1. dup系统调用对fd进行复制,会返回一个新的文件描述符(譬如原来的fd是3,返回的就是4)
  2. dup系统调用不能指定复制后得到的fd的数字是多少,由操作系统内部遵守fd的分配原则自动分配

3.2 dup的缺陷

  1. dup不能指定分配新文件描述符的数字

3.3 dup对输出的重定位

0、1、2这三个fd被标准输入、输出、错误通道占用,用close(1)关闭标准输出,使用dup重新分配得到1这个fd,就把oldfd打开的这个文件和1这个标准输出通道给绑定起来了。这就叫标准输出的重定位

#define FILENAME	"1.txt"
int main(void)
{
	int fd1 = -1, fd2 = -1;	
	fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd1 < 0)
	{
		perror("open");
		return -1;
	}
	printf("fd1 = %d.\n", fd1);	
	close(1);		// 1就是标准输出stdout	
	// 复制文件描述符
	// fd2一定等于1,因为前面刚刚关闭了1,这句话就把	
	// 1.txt文件和标准输出就绑定起来了,所以以后输出到标准输出的信息就可以到1.txt中查看了。
	fd2 = dup(fd1);	
	printf("fd2 = %d.\n", fd2);
	printf("this is for test");	
	close(fd1);
	return -1;
}

四、文件属性

4.1 文件的权限列表

在linux中 ls -l 打印出来的权限一共9位,3个一组

  1. 第1组3个表示文件的属主(owner、user)对该文件的可读、可写、可执行权限
  2. 第2组3个表示文件的属主所在的组(group)对该文件的可读、可写、可执行权限
  3. 第3组3个表示其他用户(others)对该文件的可读、可写、可执行权限

4.2 access函数检查权限设置

  1. 在操作文件之前先判断当前是否有权限做这个操作,如果有再做,如果没有则提供错误信息给用户。
  2. access函数可以测得,当前执行程序的用户在当前环境下,对目标文件是否具有某种操作权限。
  3. access函数失败返回-1
#define NAME 	"1.txt"
int main(void)
{
	int ret = -1;
	ret = access(NAME, F_OK);//判断是否可以打开		
	ret = access(NAME, R_OK);//判断是否可读
	ret = access(NAME, W_OK);//判断是否可写
	ret = access(NAME, X_OK);//判断是否可执行
	return 0;
}

4.3 用命令修改权限

  1. chmod是一个linux命令,用来修改文件的各种权限属性
  2. chmod命令只有root用户才有权利去执行修改
  3. chmod命令其实内部是用linux的一个叫chmod的API实现的
#define NAME 	"1.txt"
int main(void)
{
	int ret = -1;
	ret = chmod(NAME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWOTH);	
	return 0;
}

4.4 用命令修改属主

  1. chown命令来修改文件属主
  2. chown命令是用chown API实现的

4.5 文件权限掩码

  1. 文件掩码是linux系统中维护的一个全局设置
  2. umask的作用是用来设定我们系统中新创建的文件的默认权限的
  3. umask命令就是用umask API实现的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值