关于Linux C用到的一些重要的知识点 接上个文件

  • write

    • 作用:write系统调用用来将数据写入已经打开的文件当中

    • 原型:

    
    #include<unistd.h>
    
    ssize_t write(int fd,const void *buf,size_t count);
    • 参数:将buf所指向缓冲分区的count个字节数据写入到有文件描述符fd指向的文件中。

    • 成功:返回写入的字节数

    ​ 错误:返回-1

  • lseek

    • 作用:移动文件读写指针的位置

    • 原型:

    
    #include<sys/types.h>
    
    
    #include<unistd.h>
    
    off_t lseek(int fildes,off_t offset,int whence);
    • 打开文件时,读写位置指文件开头

    添加方式打开文件(open函数使用了O_APPEND),读写位置指向文件尾

    • 参数:

    • fildes:打开的文件描述符

    • offset:根据whence来移动读写位置的移动数
    • whence:有三种

    SEEK_SET:从文件开始计算偏移量

    SEEK_CUR:从文件当前位置

    SEEK_END:从文件结尾处

    • lseek允许文件指针的值设置到EOF后,这样并不改变文件的大小,如果使用write对EOF之后的位置写入数据后,之前的EOF处与后面已写入的数据间将存在一个间隔,用read读这个间隔时,为0

    • 成功:返回当前读写位置

    ​ 失败:返回-1

    • ##### 常用的方法
    1.将文件读写指针移到文件开头
    lseek(int fildes,0,SEEK_SET);

    2.将文件读写指针移到文件结尾

    lseek(int fildes,0,SEEK_END);

    3.获取文件读写指针当前的位置(相当于文件开头的偏移)

    lseek(int fildes,0,SEEK_CUR);
    • linux下,不允许lseek()对tty设备进行操作,此操作会返回错误代码ESPIPE

    • 运用:

    
    #include<stdio.h>
    
    
    #include<stdlib.h>
    
    
    #include<sys/types.h>
    
    
    #include<unistd.h>
    
    
    #include<sys/stat.h>
    
    
    #include<fcntl.h>
    
    
    #include<errno.h>
    
    /*自定义的错误处理函数*/
    void my_err(const char *err_string,int line)
    {
        fprintf(stderr,"line:%d ",line);
        perror(err_string);
        exit(1);
    }
    /*自定义的读数据函数*/
    int my_read(int fd)
    {
        int len;
        int ret;
        int i;
        char read_buf[64];
        /*获取文件长度并保持文件读写指针在文件开始*/
        if(lseek(fd,0,SEEK_END)==-1)
            my_err("lseek",__LINE__);
        if((len=lseek(fd,0,SEEK_CUR))==-1)
            my_err("lseek",__LINE__);
        if((lseek(fd,0,SEEK_END))==-1)
            my_err("lseek",__LINE__);
        /*读数据*/
        if((ret=read(fd,read_buf,len))<0)
            my_err("read",__LINE__);
        /*打印数据*/
        for(i=0;i<len;i++)
            printf("%c",read_buf[i]);
        printf("\n");
        return ret;
    }
    int main(void)
    {
        int fd;
        char write_buf[32]="hello world!";
        /*在当前目录下创建文件*/
        if((fd=open("example_63.c",O_RDWR|O_CREAT|O_TRUNC,S_IRWXU))==-1)
            my_err("open",__LINE__);
        else
            printf("creat file success\n");
        /*写数据*/
        if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
            my_err("write",__LINE__);
        my_read(fd);
        /*演示文件的间隔*/
        printf("/*--------*/");
        if(lseek(fd,10,SEEK_END)==-1)
            my_err("lseek",__LINE__);
        if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
            my_err("write",__LINE__);
        my_read(fd);
        close(fd);
        return 0;
    }
    • LINE 22-27:很巧妙,先将文件指针移到尾,再用SEEK_CUR计算文件的长度,再移到头
  • dup和dup2
    • 作用:用来复制文件描述符

    • 原型:

    
    #include<unistd.h>
    
    int dup(int oldfd);
    int dup2(int oldfd,int newfd);
    • dup:用来复制oldfd指的文件描述符,复制成功时,返回最小的尚未使用的文件描述符

    • 成功:返回新的文件描述符(和oldfd指向同一个文件,共享所有的锁定,读写指针和各项权限或标志位等)

    • 失败:返回-1

    • dup2:用参数newfd指定新的文件描述符的数值

    • 如果newfd被程序用了,系统会关闭释放该描述符

    • 如果oldfd与newfd相同,返回newfd而不关闭它
    • 成功:返回描述符 失败:返回-1
  • stat/fstat/lstat
    • 作用:获取文件属性

    • 原型

    
    #include<sys/types.h>
    
    
    #include<sys/stat.h>
    
    
    #incldue<unistd.h>
    
    int stat(const char *file_name,struct stat *buf);
    int fstat(int filedes,struct stat *buf);
    int lstat(const char *file_name,struct stat *buf);
    • 区别

    • fstat:通过文件描述符指定文件

    • stat:获取参数file_name指定的文件名的状态信息,保存在struct stat *buf中,对于符号连接文件,返回的是符号链接文件指向的文件状态信息
    • lstat:对符号链接,返回链接文件本身的状态信息

    • 成功:返回0 失败:返回-1

    • 参数有:

struct中的东西含义
st_dev文件的设备编号
st_ino文件的i-node
st_mode文件的类型和存取权限
st_nlink硬链接数目,新建立的文件值:1
st_uid文件所有者的用户id
st_gid文件所有者的组id
st_rdev若设备文件,则为设备编号
st_size文件大小(字节算)(符号链接:指向的文件名长度)
st_blksizeI/O缓存区的大小
st_blcoks占用文件区块的个数,每一块大小通常为512个字节
st_atime最近一次访问的时间
st_mtime最后一次修改的时间(调用utime write才会改变)
st_ctime最近一次更改的时间(此参数在文件所有者,所属组,文件权限被更改时才更新)

st_mode包含文件类型信息:

S_ISLINK符号链接
S_ISREG一般文件
S_ISDIR目录文件
S_ISCHR字符设备文件
S_ISBLK块设备文件
S_ISFIFO先进先出FIFO
S_ISSOCKsocket

那怎样用呢?

c
if(S_ISLNK(st_mode))
printf("l");

原因是什么?

找到他的定义,就会一目了然://将S换成F找对应的

c
#define S_ISLNK (m(((m)&&S_IFMT)==S_IFLNK)

S_ISLNK 实际是一个掩码,ta的值为017000(八进制,用来过滤出前四位 来判断文件的类型)

define S_IFMT 00170000
define S_IFSOCK 0140000
define S_IFLNK 0120000
define S_IFREG 0100000
define S_IFBLK 0060000
define S_IFDIR 0040000
define S_IFCHR 0020000
define S_IFIFO 0010000
define S_ISUID 0004000
define S_ISGID 0002000
define S_ISUTX 0001000

* #### getcwd

  • 作用:获取当前目录

  • 原型:

    
    #include<unistd.h>
    
    char *getcwd(char *buf,size_t size);
    char *get_current_dir_name(void);
    char *getwd(char *buf);
  • getcwd:

    • 将当前工作目录绝对路径复制到参数buf指的内存空间,size为buf的空间大小(buf要足够大)
    • 工作目录绝对路径的字符串长度超过size的大小,返回NULL,errno=ERANGE
    • buf=NULL getcwd()根据size大小自动分配内存
    • buf=NULL size=0 则根据工作目录绝对路径的字符串长度来决定配置的内存大小,用完此字符串后free掉
  • 成功:将结果复制到buf所指的内存空间,或返回自动配置的字符串指针

  • 失败:NULL

    • #### chdir
  • 作用:更改当前工作目录

  • 原型:

    
    #include<unistd.h>
    
    int chdir(const char *path);
    int fchdir(int fd);
  • (chdir):将当前工作目录改为path指定的目录

    (fchdir):将当前工作目录改为由fd指定的目录

    • #### opendir
  • 只要对目录有读权限,就可以获取目录信息

  • 作用:打开目录

  • 原型:

    
    #include<sys/types.h>
    
    
    #include<dirent.h>
    
    DIR *opendir(const char *name);

    opendir用来打开参数name指定的目录,并返回DIR *形态的目录流,(类似文件描述符)

  • 成功:返回DIR *目录流

  • 失败:返回NULL

    • #### readdir
  • 作用:读取目录项信息,返回一个struct dirent结构的指针

  • 原型:

    
    #include<sys/types.h>
    
    
    #include<dirent.h>
    
    struct dirent *readdir(DIR *dir);

    结构体里面有个d_name是指以NULL结尾的文件名

    • #### closedir
  • 作用:关闭dir指向的目录

  • 原型:

    
    #include<sys/types.h>
    
    
    #include<dirent.h>
    
    int closedir(DIR *dir);
  • 成功:返回0

  • 失败:返回-1

一定要记着打开目录后一定要关,因为在做ls的时候,因为没有关闭目录就导致了一些错误,而且这种错误不易被发现,所以一定要注意


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值