栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux基础4

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux基础4

linux基础4

1.编写makefile文件
2._c库函数
3.系统IO函数
4.关于目录操作
5.dup/dup2
6.fcntl

1.编写Makefile文件

Makefile代码管理工具,记录编译程序的步骤

	1.Makefile的命名
		makefile/Makefile:只能这两种之一
		编写完后,直接 make 执行
	2.makefile的规则:
		规则中的三要素:目标、依赖、命令
		方式1:
		在文件中如下格式,目标两个字顶格,命令前有个Tab空格,如下图所示,命令可以是多条命令
			目标:依赖条件
				命令

		方式2:
		子目标和终极目标:如果有多条规则,默认最上方的目标为终极目标,其它为子目标
			更新目标的原则:
			特点:此方式下,更改某个c文件,make后不会重新编译所有c文件,而是只编译对应修改的文件,其它文件直接链接


	3.makefile 工作原理
		在更新时,首先检查每个.c文件和其生成的.o文件,如果.o文件的创建时间早于.c文件,说明.c文件进行了更新,则需要进行编译,否则不需要编译,只用链接就行,然后如果判断最终文件,如果最终文件的创建时间早于.o文件,则需要进行重新链接所有.o文件,更新最终目标文件

	4.makefile中的变量
	app:main.o sub.o mul.o
		gcc main.o sub.o mul.o -o app
	
	模式匹配
	%o:%c
		gcc -c $< -o $@
	makefile自动变量
	$<:规则中的第一个依赖
	$@:规则中的目标
	$^:规则中的所有依赖
	这三个自动变量只能在规则的命令中使用,也就是上面gcc行
	下图中,obj、target为自定义变量
	$(obj):表示取obj的值


	4.makefile函数:
		所有makefile函数都有返回值
		获取指定目录下的.c文件
			src = $(wildcard .


	//文件截断
	fd = open("myhell",O_RDWR|O_TRUC);
	if(fd==-1)
	{
		perrot("open file");
		exit(1);
	}
	printf("fd = %dn",fd);
	//关闭文件
	int ret = close(fd);
	printf("ret=%dn",ret);
	if(ret==-1)
	{
		perror("close file");
		exit(1);
	}
}
2.read
	#include
	ssize_t read(int fd,void* buf,size_t count);
		fd:文件描述符
		buf:用户提供的缓冲区,通过malloc一个内存或者提供一个数组的地址,每次读完后数据存储在buf中
		count:缓冲区大小
	返回值:
		-1:读文件失败
		0:文件读完了
		>0的值:读出来的字节数
		

3.write
ssize_t write(int fd ,const void *buf,size_t count);
	返回值:
		-1:写入失败
4.close
	返回值:
5.读大文件--写入另一个文件
	read write -- 每次1个byte
	getc puts -- 每次读一个byte --效率更高
		标准c库中有一个缓冲区,因此,使用c库函数,会先在用户区使用缓存收集一定数量的字节数的数据,当缓冲区满了之后再放入内核区(内核区也有缓存4KB),再写入磁盘中,而使用read和write,会每读一个字节就会经历2上述过程一次,频繁的状态转换导致效率更低
#include
#include
#include
#include
#include
#include
int main()
{
	//打开一个文件
	int fd= open("english.txt",O_RDONLY);
	if(fd==-1)
	{
		perror("open");
		exit(1);
	}
	//创建一个新文件
	int fd1 = open("newfile",O_CTEAT|O_WRONLY,0664);
	if(fd1==-1)
	{
		perror("creat");
		exit(1);
	}
	//read file
	char buf[2048]={0}
	int count = read(fd,buf,sizeof(buf));
	if(count  ==-1)
	{	
		perror("read");
		exit(1);
	}
	while(count)
	{
		//将读出的数据写入另一个文件中
		int ret=write(fd,buf,count)
		printf("write bytes %dn",count);
		//continue read  file
		count = read(fd,buf,sizeof(buf));
	}
	//close file
	close(fd);
	close(fd1);
}
6.lseek:移动文件指针或者获取文件的长度
	#include
	#include
	off_t lseek(int fd ,off_t offset,int whence)
		offset:文件指针的偏移量,这个偏移量指的是从whence起向后便宜的长度
		whence:
			SEEK_SET:文件开始位置
			SEEK_CUR:文件当前位置
			SEEK_END:文件末尾位置
	返回值:到偏移量的大小
作用 :
	1.获取文件大小
 	2.移动文件指针
 	3.文件拓展
#include
#include
#include
#include  //close 头文件
#include  //exit头文件
#include 	//perror头文件
int main()
{
	int fd;

	//打开文件
	fd=open("aa",O_RDWR);
	if(fd==-1)
	{
		perrot("open file");
		exit(1);
	}
	//获取文件长度
	int ret=lseek(fd,0,SEEK_END);
	printf("file length = %dn",ret);
	//在文件尾部向后拓展2000byte
	ret =lseek(fd,2000,SEEK_END);//也可以从当前位置拓展使用,SEEK_CUR
	printf("return value = %dn",ret);
	//实现文件拓展,需要再最后做一次写操作,写的数据会继续增加文件的大小,并且位于文件的末尾
	write(fd,"a",1);
	close(fd);
	return 0;
}
7.stat函数:获取文件信息
	stat 文件名字
int stat(const cahr *path,struct stat *buf);
	穿透(追踪)函数--软链接
int fstat(int fd,struct stat *buf);
int lstat(const char *path,struct stat *buf);
	不穿透函数(追踪)
	第一个函数和第三个函数,如果读普通文件的大小,则是相同的,如果读软链接的大小,则第一个函数读的实际是映射到的文件的大小,而第二个实际是软链接的大小

	像类似于struct stat *buf的参数一般都是传出参数,也就是在函数外定义一个该类型的结构体变量,取该变量的地址作为参数传入,变量所指的实际数据,会在函数内指定,然后在函数外,可以使用变量获取执行的结果数据。

		在/etc/passwd中查看用户ID和组ID

	可以通过truncate函数,传入一个比原文件大的长度,从而扩展文件大小


当需要一个临时文件时,可以先创建一个文件,然后使用unlink函数绑定改文件,当该文件被关闭时,文件就会被自动删掉

#include
#include
#include
#include  //close 头文件
#include  //exit头文件
#include 	//perror头文件
int main()
{
	int fd;

	//打开文件
	fd=open("tempfile",O_CREAT|O_RDWR,0664);
	if(fd==-1)
	{
		perrot("open file");
		exit(1);
	}
	//删除临时文件
	int ret=unlink("tempfile");
	//write file
	write(fd,"hello",5);
	
	//重置文件指针
	ret =lseek(fd,0,SEEK_SET);//也可以从当前位置拓展使用,SEEK_CUR
	//read file
	char buf[24]={0};
	int len=read(fd,buf,sizeof(buf));
	//将结果写在屏幕上1--std_out标准输出屏幕,0--std_in ,2--std_error
	write(1,buf,len)
	close(fd);
	return 0;
}

4.关于目录操作


chdir函数相当于cd命令,用来切换目录,getwd相当与pwd用于获取当前路径


#include
#include
#include
#include  //close 头文件
#include  //exit头文件
#include 	//perror头文件
int getFileNum(char* root)
{
	//open dir
	DIR * dir = NULL;
	dir = opendir(root);
	if(dir==NULL)
	{
		perror("opendir");
		exit(1);
	}
	//遍历当前打开的目录
	struct dirent* ptr=NULL;
	char path[1024]={0};
	int total=0;
	while((ptr=readdir(dir))!= NULL)
	{
		//过滤掉 . 和 ..
		if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0)
		{
			continue;
		}
		if(ptr->d_type==DT_DIR)
		{
			//递归读目录
			sprintf(path,"%s/%s",root,ptr->d_name)
			total=getFileNum(path);
		}
		//普通文件
		if(ptr->d_type==DT_REG)
		{
			total++;
		}
	}
	colsedir(dir);
	return total;
	
}
int main(int argc,char * argv[])
{
	fi(argc<2)
	{
		printf("./a.out dirn")
		exit(1);
	}
	int total=getFileNum(argv[1]);
	printf("%s has file number %dn",argv[1],total);
	return 0;
}
5.dup/dup2函数
复制现有的文件描述符
dup
	int dup(int oldfd);
		返回新的文件描述符,该文件描述符为文件描述符列表中最小的没有被占用的文件描述符
dup2
	int dup2(int  oidfd,int newfd);
		1.old,new不同,如果new是一个被打开的文件描述符,在拷贝前会先关掉new对应的文件,调用后,old和new指向统一个文件,该文件,是old原来对应的文件,对于每个文件描述符,都需要调用close(new),close(new);
		返回值为-1时,拷贝失败。
		2.如果old与new是同一个文件描述符,不会关掉new,会直接返回这个文件描述符
6.fcntl函数
改变已打开的文件的属性
	例如:
		打开时只读
			修改文件属性:添加追加O_APPEND


当cmd为F_GETFL时,第三个参数为0

#include
#include  //close 头文件
#include  //exit头文件
#include 	//perror头文件
int main()
{
	int fd;
	//测试字符串
	char *p="我们是一个中国特色社会主义国家"
	char *q="呵呵,社会主义好啊。。。。。"
	//打开文件
	fd=open("tempfile",O_WRONLY);
	if(fd==-1)
	{
		perrot("open file");
		exit(1);
	}
	if(write(fd,p,strlen(p))==-1)
	{
		perror("write");
		exit(1);
	}
	//使用F_GETFL命令得到文件状态标志
	flag = fcntl(fd,F_GETFL,0)
	if(flag==-1)
	{
		perrot("fcntl");
		exit(1);
	}
	//将文件标志添加“追加写”选项
	flag|=O_APPEND;
	//将文件状态改为追加写
	if(fcntl(fd,F_SETFL,flag)==-1)
	{
		perror("fcntl -- append write");
		exit(1);
	}
	//再次输入新内容,该内容会追加到旧内容的后面
	if(write(fd,q,strlen(q))==-1)
	{
		perror("write again");
		exit(1);
	}
	close(fd);
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/944815.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号