Linux系统编程【04

Linux系统编程【04,第1张

目录

文件描述符

Fcntl函数

lseek函数

应用场景:

常见参数:

传入参数:

传出参数:

传入传出参数:

文件存储

 stat函数

link/unlink函数


文件描述符

PCB进程控制块:本质是结构体

成员:文件描述符表

文件描述符:0-1023 表中可用的最小的

        0-STDIN_FILENO

        1-STDOUT_FILENO

        2-STDERR_FILENO

阻塞、非阻塞:是设备、网络文件的属性

产生阻塞的场景:读设备文件、读网络文件。


(读常规文件无阻塞概念)

Fcntl函数

fcntl函数类似一个杂货铺,本文主要描述使用fcntl来改变文件属性

Fcntl函数

    int flags = fcntl(fd, F_GETFL);
    flags |= O_NONBLOCK;
    fcntl(fd, F_SETFL, flags);

        获取文件状态:F_GETFL

        设置文件状态:F_SETFL

e.g.

int main(void) 
{
    char buf[10];
    int flags, n;
    
    flags = fcntl(STDIN_FILENO, F_GETFL);
    if(flags == -1) {
        perror("fcntl error");
        exit(1);
    }
    flags |= O_NONBLOCK;
    int ret = fcntl(STDIN_FILENO, F_SETFL, flags);
    if(ret == -1) {
        perror("fcntl error");
        exit(1);
    }
}
lseek函数

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

        参数:

                fd:文件描述符

                offset:偏移量

                whence:起始偏移量 SEEK_SET/SEEK_CUR/SEEK_END

        返回值:

                成功:较起始位置偏移量

                失败:-1, errno

读和写使用一个偏移量

e.g.

int main() 
{
    int fd, n;
    char msg[] = "it is a test for lseeek\n";
    char ch;
    
    fd = open("lseek.txt", O_RDWR | O_CREAT, 0644);
    if(n < 0) {
        perror("open error");
        exit(1);
    }

    write(fd, msg, strlen(msg));
    lseek(fd, 0, SEEK_SET);    //读和写光标使用同一个位置,如果将此句注释掉,结果会读出0数据
                               //因为write函数写完之后,光标在文件的末尾
    while((n = read(fd, &ch, 1))) {
        if(n < 0) {
            perror("read error");
            exit(1);
        }
    }
    write(STDOUT_FILENOM, &ch, n);
    close(fd);
}
应用场景:

        1、文件的读和写使用同一偏移量

        2、使用lseek去获取文件大小。


                int i = off_t lseek(fd, 0, SEEK_END);

        3、使用lseek去拓展文件大小、要想使文件大小真正拓展,必须引起IO *** 作

                可以使用truncate函数,直接拓展文件

                int ret = truncate("lseek.txt", 200);

常见参数: 传入参数:

        1:指针作为函数参数

        2:通常由const关键字修饰

        3:指针指向有效区域,在函数内部做读 *** 作

传出参数:

        1:指针作为函数参数

        2:在函数调用之前,指针指向的空间可以无意义,但必须有效

        3:在函数内部,写 *** 作

        4:函数调用结束后,充当返回值

传入传出参数:

        1:指针作为函数参数

        2:在函数调用之前,指针指向的空间有实际意义

        3:在函数内部,先做读 *** 作,再做写 *** 作

        4:函数调用结束后,充当返回值

文件存储

        inode:其本质为结构体,存储文件的属性信息。


如:权限、类型、大小、时间、用户、盘块位置...也叫作文件属性管理结构,大多数的inode都存储在磁盘上

        dentry:目录项,其本质也是结构体,重要成员变量有两个:文件名、inode;而文件内容保存在磁盘盘块上

 stat函数

        获取文件属性,从inode结构体中获取

        int stat(const char *path, struct stat*buf);

        参数:

                path:文件路径

                buf:(传出参数)存放文件属性

        返回值:

                成功:0

                失败:-1, errno

struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

               #define st_atime st_atim.tv_sec      /* Backward compatibility */
               #define st_mtime st_mtim.tv_sec
               #define st_ctime st_ctim.tv_sec
           };
    

e.g.

int main(int argc, char *argv[])
{
    struct stat, sbuf;
    int ret = stat(argv[1], &sbuf);
    if(ret == -1) {
        perror("stat error");
        exit(1);
    }
    int reg = S_ISREG(sbuf.st_mode);
    printf("reg = %d\n", reg);

    return 0;
}

stat和lstat函数区别:

        stat会穿透符号链接

        lstat不会穿透符号链接

link/unlink函数

        隐式回收:当进程结束运行时,所有该进程打开的文件会被关闭,申请的内存空间会被释放,系统的这一特性称之为隐式回收系统资源

        我们删除文件时,从某种意义上讲,只是让文件具备了被释放的条件,清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件不会马上被释放,要等到所有打开该文件的进程关闭该文件,系统才会调时间将该文件释放掉

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/579111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存