Linux_基础编程day03

将近日学习Linux基础编程,系统编程,网络编程的word笔记搬运过来,图片无法直接粘贴,就丢失掉了。

日后工作学习中使用与扩充维护还是word笔记

这篇文章图片很多,亏大了。

基础编程day03

内容简介:
学习目标:

1 掌握read/write/lseek函数的使用

2 掌握stat(穿透)/lstat函数的使用

3 了解文件属性相关的函数使用

4 了解目录操作相关的函数的使用

5 掌握目录遍历相关函数的使用,和读文件类似打开,读,关闭

6 掌握dup,dup2函数的使用,复制文件描述符,多个文件描述符指向同一个磁盘文件

7 掌握fcntl函数的使用,在文件打开后追加属性,有5大类功能

内容简介:

lseek

         对文件指针set,cur,append,返回的是off_t与文件头部的距离

stat函数

         stat命令,struct stat

文件操作

access,chmod,chown,truncate

目录操作

         rename,chdir,getcwd,mkdir,rmdir

目录遍历

         opendir,DIR *,struct dirent,readdir,记得关闭

dup复制文件描述符

         dup2恋旧

fcntl

         复制文件描述符,改变文件状态(读写属性不能改)

复习:

1makefile

一个规则

目标:依赖

(tab缩进)命令

                   可以有多个规则

                            make  直接生成终极目标

                                     第一个规则对应的目标

                            make+子目标的名字

                                     就会生成子目标,和终极目标没关系

         工作原理

                   依赖不存在:

                            向下查找子规则,找到了用来生成依赖的规则,执行里面的命令

                   依赖存在->更新检查

                            更新条件:目标时间<依赖时间

         两个函数:

                   wildcard搜索指定目录下指定的文件

                            src = $(wildcard ./src/*.c)

                            src= ./src/a.c ./src/b.c ./src/c.c

                   patsubst

                            obj = $(patsubst %.c, %.o, $(src) ) ;

                            把*.c都替换为*.o,*.c是从src中得到的

                            obj= ./src/a.o ./src/b.o ./src/c.o

         三个自动变量

                            $@:规则中的目标

                            $<:规则中的第一个依赖

                                     app:a.o b.o c.o

                                               gcca.o b.o c.o –o app

                            $^:规则中的所有依赖

                  模式规则:像公式一样,每遇到需要生成.o文件,就来这里套用

                            %.o:%.c

                                     gcc –c &< -o &@

         清空项目

                   声明伪目标:说明这个目标是个假的目标,不需要做更新检查

                   .PHONY:clean

                   clean:

                            -rm*.o

         目标不是必须在命令中生成,只是一个格式

 

作业:一个很大的文件,open数据读出来,read读出来后写入另一个文件

通过read的返回值可以判断是否读完(>0)

write函数第三个参数为buf中有效的字节数,如果使用strlen函数,必须要保证buf中最后一个字符是\0,如果不能保证,那么请用read函数的返回值来作为有效字节数。

或:把buf[4095]初始化为\0,且read的时候sizeof(buf)-1

通过read的返回值判断是否到达文件尾部

 

系统函数调用失败,返回值一般都是-1

erro no是系统函数库的全局变量

 

perror(const char *s)根据errno的值打印相应的错误信息,s会先被打印。一般是函数的名字,这样在打印错误信息时,能快速定位错误位置。

 

lseek

      函数原型:off_t lseek(int fd, off_t offset, int whence);

                   SEEK_SET:头部

                   SEEK_CUR:当前位置

                   SEEK_END:尾部

      使用:
              文件指针移动到头部

                            lseek(fd,0, SEEK_SET); 返回值是0

              获取文件指针当前位置

                            intlen = lseek(fd, 0, SEEK_CUR);

              获取文件长度

                            intlen =  lseek(fd, 0, SEEK_END);

文件拓展

                   文件原大小100k,拓展为1100k,

                            lseek(fd,1000, SEEK_END);

                            write(fd,“a”, 1);若想拓展成功,必须进行一次写操作,往文件尾部写一个数据

                            作用:迅雷下载的时候,文件10G,刚开始下载的时候,文件就是10G,就是使用了文件拓展:1占位作用2方便多线程指针后移

阻塞和非阻塞

         阻塞:代码执行到这里,就不再向下执行,只有条件满足才会继续向下执行。

         阻塞非阻塞是文件的属性还是read等函数的属性:文件的属性

 

STDIN_FILENO是标准输入的文件描述符

终端会被抽象为设备文件,放在dev下,tty就是不同的终端dev/tty就是当前终端

 

ld…未找到命令出现的原因:

默认bash是前台程序

./block_read启动了一个程序,前台程序变成了./block_read,bash变成了后台程序,

./block_read等待用户输入10个字符,实际输入的>10个字符,剩下的还在缓冲区中,read解除阻塞读缓冲区数据,write函数完毕后,程序结束

bash从后台程序变为前台程序,检测到了缓冲区中有数据,把缓冲区的数据作为shell命令进行解析

打开终端,默认的就是阻塞的,O_NONBLOCK设置的是打开文件的状态

读终端的时候没有数据,errno=EAGAIN,可以sleep(3),write(STDOUT_FILENO, “try again”, strlen(“try again”) ) ;

 

阻塞非阻塞是文件的属性

         读写普通文件:hello.c

                   默认不阻塞

         读写终端设备:dev/tty

                   默认阻塞

                   管道

                   套接字

stat函数,获得文件信息

stat命令的效果(shell命令):

ctime atime mtime

最近改动:文件属性改变,就叫改动

使用stat函数头文件:

1<sys/types.h>  2<sys/stat.h>  3<unistd.h>

stat函数声明

intstat(const char *pathname, struct stat *buf) ;成功返回0,失败返回-1

                   通过*buf指针修改实参的值

 

stat结构体

注意蓝色的字,是用来做&操作的,过滤掉无关位

 

 

与掩码做&操作,作用:针对某功能,过滤其他位

 

 

(st.st_mode & S_IFMT) == S_IFREG

if(st.st_mode & S_IFREG)                  判断该位是否为1

 

穿透

int lstat(const char *pathname, struct stat*buf) ;

与stat区别,读软连接文件(ln–s main.c m.s)的时候,读到的是软连接.s文件的信息,而stat函数读取的链接文件指向的文件的属性,称为追踪或穿透。

         应用场景:实现ll m.s的时候

int fstat(int fd, struct stat *buf);

         通过文件描述符获取文件属性。

文件操作:access,chmod,chown,truncate,

 

获取当前用户对文件权限int access(const char *pathname, int mode);

         头文件:unistd.h

检测当前用户对文件的权限,R_OK,W_OK,X_OK,

判断文件是否存在F_OK(是否存在)

有就返回0,没就返回-1

 

修改文件权限int chmod(const char*pathname, int mode);

         filename:文件名

         mode:八进制数

strtol把字符串转化为不同进制的数字

 

修改文件所有者所属组int chown(const char *path, uid_t owner, gid_t group);

         其中owner和group都是ID号

         etc/passwd,etc/group中可以找到ID号

 

修改文件大小int truncate(const char *path, off_t length);

         参数:

                  length是文件的最终大小

                            比原来小,删除后边的部分

                            比原来大,向后拓展,加占位符,空洞

                   path:文件名

 

目录操作:rename,chdir,getcwd,mkdir,rmdir

目录重命名:

         intrename(const char *oldpath, const char *newpath);

修改当前进程(应用程序)的路径

         intchdir(const char *path);

                   参数:切换到的目录

获取当前进程的工作目录

         chargetcwd( char *buf, size_t size);

                   通过*buf修改实参的值,将结果放入buf指向的内存中,size是buf的大小

创建目录mkdir

         intmkdir(const char *pathname, mode_t mode);

                   参数:

                            pathname创建的目录名

                            mode:目录权限,八进制数实际权限& ~u_mask &0777

删除空目录:

int rmdir(constchar *pathname);

                   参数:空目录的名字

 

目录遍历相关函数opendir,dirent,closedir

1 打开一个目录DIR *opendir(constchar *name);

                   参数:目录名

                   返回值:指向目录的指针

                   DIR*与FILE*类似,后者是fopen得到的

 

2 读struct dirent*readdir(DIR *dirp);

d_type判定文件的类型

 

循环读取目录

一个目录下有三个文件,需要循环地去读

opendir之后,while(readdir() ){} ,readdir返回null后,就是文件读完了

目录是树结构。

 

关闭目录

         intclosedir(DIR *dirp) ;

 

//读指定目录中文件的个数

int get_file_num(char *root)

{

         inttotal = 0;

         //读目录

         DIR *dir = opendir(root);

         if(dir== NULL)

                   {

                            perror(“opendirerror”);

                            exit(1);

                   }

         struct dirent *ptr = NULL;

         while(  (ptr = readdir(dir) ) != NULL )

         {

                   //不处理.和..

                   if(strcmp(“.”, ptr->d_name) == 0 || strcmp(“..”, ptr->d_name) == 0 )

                   {

                            continue;

                   }

                   //判断是不是普通文件

                   if(ptr->d_type== DT_REG )

                   {

                            total++;

                   }

                   //如果是目录,递归

                  if( ptr->d_type == DT_DIR)

                   {

                            //求出子目录

                            charpath[1024] = {0};

                            sprintf(path,“%s/%s”, root, ptr->d_name) ;

                            total= total + get_file_num(path);

                   }

}

//关闭目录

closedir(dir);

         returntotal ;

}

 

命令行传参:参数传给argv[],argv[0]是可执行程序的名字,你传的参数从argv[1]开始。

argc是argv[]中元素的个数

 

文件描述符的复制(但是文件指针还是只有一个)

int dup(int oldfd) ;

         oldfd:要复制的文件描述符

         返回值:新的文件描述符(空闲的文件描述符当中最小的)

         dup调用成功:

                   有两个文件描述符指向同一个文件

f_count表示有多少个文件描述符指向这个文件

 

int dup2(int oldfd, int newfd) ; 怀旧

         能控制新的文件描述符是哪个

                   oldfd->hello

                   newfd->world

                   dup2(oldfd,newfd);

                            newfd->hello;oldfd->hello

         文件描述符的重定向:

                  假设newfd已经指向了一个文件,首先断开(close)与那个文件的链接newfd指向oldfd指向的文件

 

         newfd与oldfd指向同一个文件,则不会执行先断开再建立的操作。

 

fcntl:改变已经打开的文件的属性

变参函数

复制一个已有的文件描述符

         intret = fcntl(fd, F_DUPFD);

获取和设置文件状态标志,RDONLY?WRONLY?

         open的flags参数

         1获取文件状态标识

                   intflag = fcntl(fd, F_GETFL);

         2设置文件状态标识符

                   flag  = flag | O_APPEND;

                   fcntl(fd,F_SETFL, flag);

         可以更改的几个标识:O_APPEND O_NONBLOCK

错误操作:

         open(“temp”,O_RDONLY);

                   需要设置文件为O_RDWR,这是不可以的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值