linux并发服务器 —— 文件IO相关函数(三)

news2024/11/28 0:36:58

文件IO

以内存为主体,看待输入输出;

标准C库IO函数带有缓冲区,效率较高;

虚拟地址空间

虚拟地址空间是不存在的,一个应用程序运行期间对应一个虚拟地址空间;

虚拟地址空间的大小由CPU决定,位数不同,大小不同;

32位的机器,虚拟地址空间如下所示:

 虚拟空间会被逻辑管理单元MMU映射到真实的物理内存;

调用linux系统API(系统调用)对内核区进行操作;

文件描述符

位于进程的内核区,由PCB管理,用于定位文件,通过其实现对文件的操作;

PCB中通过数组管理文件描述符,最大为1024,前三个为0-标准输入、1-标准输出、2-标准错误,默认打开;

标准输入、标准输出、标准错位指向当前同一终端(设备文件);

不同的文件描述符对应不同的文件,一个文件可以被打开多次,多次打开的文件描述符不同

文件描述符的分配,去文件描述符表中找最小的没有分配的文件描述符进行分配即可;

Linux系统的IO函数

open打开文件

/*
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>



    // flags标记 宏定义在前两个头文件

    // 打开一个已经存在的文件
    int open(const char *pathname, int flags); 
        参数:
            pathname - 文件路径
            flags - 对文件的操作权限设置和其他设置
                只读、只写、读写 设置互斥( O_RDONLY,  O_WRONLY,  or O_RDWR)
        返回值:返回文件描述符,调用失败返回-1

        errno:属于Linux系统函数库,库里的全局变量,记录最近的错误号
        可以通过perror打印errno对应的错误描述

    // 创建一个新的文件
    int open(const char *pathname, int flags, mode_t mode);
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(){

    int fd = open("a.txt" , O_RDONLY);

    if(fd==-1){
        perror("open");
    }

    // 关闭文件描述符 使其不指向任何文件
    close(fd);

    return 0;
}

open创建新文件

/*
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    int open(const char *pathname, int flags, mode_t mode);
        新参数:
            flags - 操作权限和其他设置;
                必选项:操作权限;
                可选项:O_CREATE 文件不存在创建新文件
                int类型 32位 每一位都是一个标志位
            mode - 8进制的数,表示用户对创建出新的文件的操作权限
                最终权限:mode&~umask(不同用户umask不同,可以改)
                eg. 0777 - 最高权限  0777&~0002->0775
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(){

    //创建新的文件
    int fd = open("create.txt" , O_RDWR|O_CREAT , 0777);
    if(fd==-1){
        perror("open");
    }

    close(fd);
    return 0;
}

read、write函数

/*
    #include <unistd.h>
    
    ssize_t read(int fd, void *buf, size_t count);

    参数:
        fd - 文件描述符 open得到 通过文件描述符操作文件
        buf - 读取数据存放的地方 数组的地址
        count - 指定数组大小
    返回值
        成功 
            >0 实际读取字节数
            =0 文件读取完了
        失败
            -1 并设置errno

    ssize_t write(int fd, const void *buf, size_t count);
        参数:
            buf - 往磁盘写入的数据
            count - 要写的数据实际大小
*/

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(){

    // 1. open开
    int sfd = open("english.txt" , O_RDONLY);
    if(sfd==-1){
        perror("open");
        return -1;
    }
    // 2. 创建新的文件
    int dfd = open("cpy.txt" , O_WRONLY | O_CREAT , 0664);
    if(dfd==-1){
        perror("open");
        return -1;
    }
    // 3. 读写
    char buf[1024] = {0};
    int len = 0;
    while((len = read(sfd, buf, sizeof(buf)))>0){
        write(dfd , buf , len);
    }
    // 4. 关闭文件
    close(dfd);
    close(sfd);

    return 0;
}

lseek函数

/*
    #include <sys/types.h>
    #include <unistd.h>

    off_t lseek(int fd, off_t offset, int whence);
        参数:
            fd - 文件描述符
            offset - 偏移量
            whence - 指定标记:
                SEEK_SET
                    设置文件指针偏移量

                SEEK_CUR
                    从当前位置设置偏移量

                SEEK_END
                    从文件结尾设置偏移量
        返回值:文件指针的位置

        作用:
            1. 移动文件指针到头文件
                lseek(fd , 0 , SEEK_SET);
            2. 获取当前文件指针位置
                lseek(fd , 0 , SEEK_CUR);
            3. 获取文件长度
                lseek(fd , 0 , SEEK_END);
            4. 拓展文件长度 10b->110b
                lseek(fd , 100 , SEEK_END);
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(){
    int fd = open("hello.txt" , O_RDWR);

    if(fd == -1){
        perror("open");
        return -1;
    }
    // 扩展文件长度
    int cnt = lseek(fd , 100 , SEEK_END);
    if(cnt == -1){
        perror("lseek");
        return -1;
    }

    // 写入空数据
    write(fd , " " , 1);

    close(fd);
    return 0;
}

stat、lstat函数

/*
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    int stat(const char *pathname, struct stat *statbuf);
        作用:获取文件相关信息
        参数:
            pathname - 操作文件路径
            statbuf - 结构体变量(传出参数) 用于保存获取到的文件信息
        返回值:
            成功 - 0
            失败 - -1 设置errno
    int lstat(const char *pathname, struct stat *statbuf);
        参数:
            pathname - 操作文件路径
            statbuf - 结构体变量(传出参数) 用于保存获取到的文件信息
        返回值:
            成功 - 0
            失败 - -1 设置errno
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(){
    struct stat statbuf;
    
    int cnt = stat("a.txt" , &statbuf);

    if(cnt==-1){
        perror("stat");
        return -1;
    }

    printf("size: %ld\n" , statbuf.st_size);

    return 0;
}

stat和lstat的区别在于软链接情况;stat通过软链接查源头文件,lstat不会;

模拟实现ls -l命令

列出当前目录下的文件信息;

// 模拟实现 ls-l指令
// -rw-rw-r-- 1 nowcoder nowcoder 10 8月  28 11:02 a.txt

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>

// argc>=1 - 文件名称
int main(int argc , char* argv[]){
    // 判断输入参数的正确性
    if(argc<2){
        printf("%s filename\n" , argv[0]);
        return -1;
    }

    // 通过stat获取传入文件信息
    struct stat st;
    
    int cnt = stat(argv[1] , &st);
    if(cnt == -1){
        perror("stat");
        return -1;
    }

    // 获取文件类型和文件权限
    char perms[11] = {0}; // 用于保存文件类型和文件权限

    // 文件类型
    switch(st.st_mode & __S_IFMT){
        case __S_IFLNK:
            perms[0] = 'l';
            break;
        case __S_IFDIR:
            perms[0] = 'd';
            break;
        case __S_IFREG:
            perms[0] = '-';
            break;
        case __S_IFBLK:
            perms[0] = 'b';
            break;
        case __S_IFCHR:
            perms[0] = 'c';
            break;
        case __S_IFSOCK:
            perms[0] = 's';
            break;
        case __S_IFIFO:
            perms[0] = 'p';
            break;
        default:
            perms[0] = '?';
            break;
    }

    // 文件访问权限

    // 文件所有者
    perms[1] = (st.st_mode & S_IRUSR)?'r':'-';
    perms[2] = (st.st_mode & S_IWUSR)?'w':'-';
    perms[3] = (st.st_mode & S_IXUSR)?'x':'-';

    // 文件所在组
    perms[4] = (st.st_mode & S_IRGRP)?'r':'-';
    perms[5] = (st.st_mode & S_IWGRP)?'w':'-';
    perms[6] = (st.st_mode & S_IXGRP)?'x':'-';

    // OTHERS
    perms[7] = (st.st_mode & S_IROTH)?'r':'-';
    perms[8] = (st.st_mode & S_IWOTH)?'w':'-';
    perms[9] = (st.st_mode & S_IXOTH)?'x':'-';

    // 硬连接数
    int ln = st.st_nlink;

    // 文件所有者
    char* ur =  getpwuid(st.st_uid)->pw_name;

    // 文件所在组
    char* grp = getgrgid(st.st_gid)->gr_name;

    // 文件大小
    long int filesize = st.st_size;

    // 获取修改时间
    char* time  = ctime(&st.st_mtime);

    char mtime[512] = {0};
    strncpy(mtime , time , strlen(time) - 1);

    char buf[1024];
    printf("%s\n" , argv[0]);
    sprintf(buf , "%s %d %s %s %ld %s %s" , perms , ln , ur , grp , filesize , mtime , argv[1]);
    printf("%s\n" , buf);
    return 0;
}

文件属性操作函数

acess - 判断文件权限

/*
    #include <unistd.h>
    int access(const char *pathname, int mode);
        作用:判断文件是否由每个权限 或文件是否存在
        参数:
            pathname - 文件路径
            mode  
                F_OK 文件是否存在
                R_OK 是否有读权限
                W_OK 是否有写权限
                X_OK 是否有执行权限
        返回值
            成功 - 0
            失败 - -1
*/

#include <unistd.h>
#include <stdio.h>

int main(){

    int ret = access("a.txt" , F_OK);
    
    if(ret == -1){
        perror("access");
        return -1;
    }

    printf("文件存在\n");
    return 0;
}

chmod - 修改文件权限

/*
    #include <sys/stat.h>
    int chmod(const char *pathname, mode_t mode);

    参数:
        mode - 需要修改的权限值 八进制rwx
    返回值:
        成功 - 0
        失败 - -1
*/
#include <sys/stat.h>
#include <stdio.h>
int main(){

    int ret = chmod("a.txt" , 0775);

    if(ret == -1){
        perror("chmod");
        return -1;
    }

    printf("修改成功\n");

    return 0;
}

 

chown - 修改文件所有者/所有组

//通过 vim /etc/group 查所属组 和 id
// id 用户名可查uid 和 gid
#include <unistd.h>

int chown(const char *pathname, uid_t owner, gid_t group);

truncate - 缩减/扩展文件大小

/*
    #include <unistd.h>
    #include <sys/types.h>

    int truncate(const char *path, off_t length);
        作用:缩减/扩展文件至指定大小
        参数:
            path - 文件路径
            length - 指定最终文件大小
        返回值:
            成功 - 0
            失败 - -1
*/
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

int main(){

    int ret = truncate("b.txt" , 20);

    if(ret==-1){
        perror("truncate");
        return -1;
    }

    printf("修改文件大小成功");

    return 0;

}

目录操作函数

 mkdir

/*
    #include <sys/stat.h>
    #include <sys/types.h>

    int mkdir(const char *pathname, mode_t mode);
        作用:创建目录
        参数:
            pathname - 创建的目录路径
            mode - 权限 八进制
        返回值:
            成功 - 0
            失败 - -1
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
int main(){

    int ret = mkdir("aaa" , 0777);

    if(ret == -1){
        perror("mkdir");
        return -1;
    }

    printf("创建目录成功\n");
    
    return 0;
}

rmdir - 只能删除空目录

rename - 文件的重命名

chdir - 修改当前工作目录

getcwd - 获取当前工作路径

/*
    #include <unistd.h>
    int chdir(const char *path);
        作用:修改进程的工作目录
        参数:
            path - 需要修改的工作目录

    #include <unistd.h>
    char *getcwd(char *buf, size_t size);
        作用:获取当前工作目录
        参数:
            buf - 存储路径,指向数组
            size - 数组大小
        返回值:
            指向的一块内存 这个数据就是第一个参数

*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(){
    // 获取当前路径
    char buf[128];
    getcwd(buf , sizeof(buf));

    printf("当前工作目录:%s\n" , buf);

    // 改目录
    int ret = chdir("/home/nowcoder/linux/lesson13");

    if(ret == -1){
        perror("chdir");
        return -1;
    }

    printf("已切换目录\n");

    int fd = open("chdir.txt" , O_RDWR|O_CREAT , 0664);

    if(fd == -1){
        perror("open");
        return -1;
    }

    close(fd);


    char buf1[128];
    getcwd(buf1 , sizeof(buf1));

    printf("当前工作目录:%s\n" , buf1);

    return 0;
}

目录遍历函数

opendir

readdir

closedir

/*
    // 打开一个目录
    #include <sys/types.h>
    #include <dirent.h>
    DIR *opendir(const char *name);
        参数:
            name - 打开目录名
        返回值:
            DIR* - 目录流信息
            错误返回NULL


    // 读取目录中的数据
    #include <dirent.h>
    struct dirent *readdir(DIR *dirp);
        参数:
            dirp - opendir返回的结果
        返回值:
            struct dirent * - 读取到的文件信息
            读到末尾/失败 返回NULL

    // 关闭目录
    #include <sys/types.h>
    #include <dirent.h>
    int closedir(DIR *dirp);
        参数:opendir的返回值



*/
#define _DEFAULT_SOURCE
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int getnum(const char* path);
// 读某个目录下所有普通文件的个数
int main(int argc , char *argv[]){
    if(argc<2){
        printf("%s path\n" , argv[0]);
        return -1;
    }

    int num = getnum(argv[1]);

    printf("普通文件个数:%d\n" , num);


    return 0;
}

// 用于获取目录下所有普通文件个数
int getnum(const char* path){
    // 1. 打开目录
    DIR* dir = opendir(path);
    if(dir == NULL){
        perror("opendir");
        return -1;
    }


    // 2. 读取
    struct dirent *ptr;

    // 普通文件个数
    int tol = 0;
    
    while((ptr = readdir(dir))!=NULL){
        // 获取名称
        char* dname = ptr->d_name;

        // 忽略. ..
        if(strcmp(dname,".")==0 || strcmp(dname,"..")==0){
            continue;
        }

        // 判断是否是普通文件
        if(ptr->d_type == DT_DIR){
            // 目录
            char newpath[256];
            sprintf(newpath , "%s/%s" , path , dname);
            tol += getnum(newpath);
        }

        if(ptr->d_type == DT_REG){
            // 普通文件
            tol++;
        }
    }

    closedir(dir);

    return tol;
}

dup、dup2函数

dup - 复制文件描述符

/*
    #include <unistd.h>
    int dup(int oldfd);
        作用:复制一个新的文件描述符(指向同一文件)
    int dup2(int oldfd, int newfd);

*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(){
    int fd = open("a.txt" , O_RDWR|O_CREAT , 0664);

    int fd1 = dup(fd);

    if(fd1 == -1){
        perror("dup");
        return -1;
    }

    printf("fd: %d , fd1: %d\n" , fd , fd1);

    close(fd);

    char* str = "hello";
    int ret = write(fd1 , str , strlen(str));
    if(ret == -1){
        perror("write");
        return -1;
    }

    close(fd1);
    return 0;
}

dup2 - 重定向文件描述符

/*
    #include <unistd.h>
    int dup2(int oldfd, int newfd);
        作用:重定向文件描述符 若newfd被使用 会先关闭在指
        若oldfd==newfd 不做任何操作
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(){

    int fd = open("1.txt" , O_RDWR|O_CREAT , 0664);
    if(fd == -1){
        perror("open");
        return -1;
    }

    int fd1 = open("2.txt" , O_RDWR|O_CREAT , 0664);
    if(fd1 == -1){
        perror("open");
        return -1;
    }

    printf("fd: %d , fd1: %d\n" , fd , fd1);

    int fd2 = dup2(fd , fd1);
    if(fd2 == -1){
        perror("open");
        return -1;
    }

    // 通过fd1写数据
    char* str = "hello";
    int len = write(fd1 , str , strlen(str));
    if(len == -1){
        perror("write");
        return -1;
    }
    printf("fd: %d , fd1: %d , fd2: %d\n" , fd , fd1 , fd2);

    close(fd);
    close(fd1);
    return 0;
}

fcntl函数

1. 复制文件描述符;2. 设置/获取文件状态标志

/*
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, ...  );
        参数:
            fd - 需要操作的文件描述符
            cmd - 对文件描述符的操作
                1. 复制文件描述符 F_DUPFD
                2. 获取指定文件描述符文件状态flag(同open) F_GETFL
                3. 设置指定文件描述符文件状态 F_SETFL
                    O_APPEND 追加数据
                    O_NOnBLOCK 设置成非阻塞
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main(){

    // 复制文件描述符
    // int fd = open("1.txt" , O_RDONLY);
    
    // int ret = fcntl(fd , F_DUPFD);

    // 2. 修改/获取文件状态标志

    int fd = open("1.txt" , O_RDWR);

    if(fd == -1){
        perror("open");
        return -1;
    }

    // 获取flag
    int flag = fcntl(fd , F_GETFL);
    if(flag == -1){
        perror("fcntl");
        return -1;
    }

    flag |= O_APPEND;

    // 修改flag
    int ret = fcntl(fd , F_SETFL , flag);
    if(ret == -1){
        perror("fcntl");
        return -1;
    }
    char* str = "nihao";
    write(fd , str , strlen(str));

    close(fd);

    return 0;
}

Node: 一定要注意 如果一个文件的权限是只读 即使通过fcntl设置了O_APPEND还是不能往文件里写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/940320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity——音乐、音效

在游戏运行的过程中&#xff0c;音效的播放时机与游戏当前内容密切相关&#xff0c;而且随着场景的变化、剧情的推进&#xff0c;背景音乐也需要适时切换&#xff0c;所以恰当地控制音乐和音效的播放非常重要。音乐和音效的播放、停止、切换和音量变化等&#xff0c;都需要由脚…

堆,堆排序和TOP—K问题(C语言版)

前言 堆是一种重要的数据结构&#xff0c;堆分为大根堆和小根堆&#xff0c;大根堆堆顶的数据是最大的&#xff0c;小根堆堆顶的数据是最小的&#xff0c;堆在逻辑结构上是一颗完全二叉树&#xff0c;这棵树中如果满足根节点大于左右子树&#xff0c;每个节点都满足这个条件就是…

capl使用汇总

数组类 2维数组定义 dword data[DIDN][100];其中数组的类型是dword&#xff0c;二维数组的元素个数是DIDN值&#xff0c;第二维100表示每个数组data[i]的都是一个一维数组并且这个一维数组是100个dword数组成的 结构体 结构体定义 以下的结构体类型supDTC&#xff08;支持…

Skip Connection——提高深度神经网络性能的利器

可以参考一下这篇知乎所讲 https://zhuanlan.zhihu.com/p/457590578

禅道后台命令执行漏洞二

漏洞简介 禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体&#xff0c;是一款专业的研发项目管理软件&#xff0c;完整地覆盖了项目管理的核心流程。 禅道管理思想注重实效&#xff0c;功能完备丰富&#xff0c;…

LeetCode--HOT100题(44)

目录 题目描述&#xff1a;230. 二叉搜索树中第K小的元素&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;230. 二叉搜索树中第K小的元素&#xff08;中等&#xff09; 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你…

网络安全(黑客技术)0基础学习手册

目录梗概 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来…

prometheus+cadvisor监控docker容器

一、安装cadvisor docker pull google/cadvisor:latest二、运行容器 docker run -d \--volume/:/rootfs:ro \--volume/var/run:/var/run:rw \--volume/sys:/sys:ro \--volume/var/lib/docker/:/var/lib/docker:ro \--publish8088:8080 \--detachtrue \--namecadvisor \--priv…

【FAQ】从存储权限看HarmonyOS 3.0中应用适配

问题背景&#xff1a; HarmonyOS 3.0发布了&#xff0c;之前开发的Android的应用&#xff0c;发现系统选项中存储权限部分有变化&#xff0c;如下图&#xff1a; ”存储“权限变为”媒体和文件“&#xff0c;且只能访问”仅媒体“的文件目录。因为项目需要读取本地导入存储文件…

基金市场的冷热传递什么信号?

摘要及声明 1&#xff1a;本文主要利用实际数据进行检验&#xff0c;从定量角度分析基金发行情况与股票市场之间的关系&#xff1b; 2&#xff1a;本文主要为理念的讲解&#xff0c;模型也是笔者自建&#xff0c;文中假设与观点是基于笔者对模型及数据的一孔之见&#xff0c…

【分享】PDF如何拆分成2个或多个文件呢?

当我们需要把一个多页的PDF文件拆分成2个或多个独立的PDF文件&#xff0c;可以怎么操作呢&#xff1f;这种情况需要使用相关工具&#xff0c;下面小编就来分享两个常用的工具。 1. PDF编辑器 PDF编辑器不仅可以用来编辑PDF文件&#xff0c;还具备多种功能&#xff0c;拆分PDF文…

【python知识】用 Tkinter实现“剪刀-石头-布”和“弹球游戏 ”

一、提要 Tkinter是一个Python内置模块&#xff0c;它提供了一个简单易用的界面来创建GUI。 在实现一些动态的画面、如游戏还是需要一些创新性思维的。在本文中&#xff0c;我们将使用 Tkinter 探索 Python GUI 编程。我们将介绍 Tkinter 的基础知识&#xff0c;并演示如何使用…

【Web系列二十四】使用JPA简化持久层接口开发

目录 环境配置 1、引入依赖 配置文件 代码编写 实体类创建 JPA常用注解 Service与ServiceImpl Service ServiceImpl Controller Dao 三种实现Dao功能方式 1.继承接口&#xff0c;使用默认接口实现 2.根据接口命名规则默认生成实现 3.自定义接口实现(类似MyBatis…

Windows-docker集成SRS服务器的部署和使用

Windows-docker集成SRS服务器的部署和使用 一、Windows Docker安装 Docker Desktop 官方下载地址&#xff1a; https://docs.docker.com/desktop/install/windows-install/ 下载windows版本的就可以了。 注意&#xff1a;此方法仅适用于 Windows 10 操作系统专业版、企业版、…

C语言之数组题

目录 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 5.扫雷 6.概念辨析tips 我又来了&#xff0c;今天是数组题&#xff0c;本人还在补军训真的热&#xff01;&#x1f197; 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 …

Python自动化测试之线上流量回放:录制、打标、压测与平台选择

在自动化测试中&#xff0c;线上流量回放是一项关键技术&#xff0c;可以模拟真实用户的请求并重现线上场景&#xff0c;验证系统的性能和稳定性。本文将介绍Python自动化测试中的线上流量回放技术&#xff0c;并提供实战代码&#xff0c;帮助你了解流量的录制、打标、压测发起…

Ubuntu安装JDK8(直接下载jdk压缩包方式)

1.官网下载JDK 地址: https://www.oracle.com/java/technologies/downloads/ 选择相应的 .gz包下载 2.解压缩,放到指定目录 创建目录: sudo mkdir /usr/lib/jvm 解压缩到该目录: sudo tar -zxvf jdk-8u381-linux-x64.tar.gz -C /usr/lib/jvm 3.配置环境变量 sudo vim ~/.ba…

跨专业申请成功|金融公司经理赴美国密苏里大学访学交流

J经理所学专业与从事工作不符&#xff0c;尽管如此&#xff0c;我们还是为其成功申请到美国密苏里大学经济学专业的访问学者职位&#xff0c;全家顺利过签出国。 J经理背景&#xff1a; 申请类型&#xff1a; 自费访问学者 工作背景&#xff1a; 某金融公司经理 教育背景&am…

YUV数据图形化理解

以下为音视频基础数据的图像化展示&#xff0c;方便大家理解 RGB24 RGB交替排列&#xff0c;RGBRGBRGB 占用空间Width*Height*3 YUV420P YU12(I420) 每4个Y分量&#xff0c;共一个UV分量 Y是连续的&#xff0c;U也是连续的&#xff0c;V也是连续的 占用空间 Width*Height …