IO进程线程-文件IO(结)

目录

 

1.文件属性相关函数

getpwuid()

getgrgid()

2.操作目录相关函数

opendir()

closedir()

readdir()

实例

3.进程

4.作业

4.1题

4.2题


1.文件属性相关函数

getpwuid()

#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwuid(uid_t uid);
功能: 通过uid获取对应的用户信息
参数:
    uid: 要获取信息uid(可以通过stat()获取uid)
    
返回值: 成功返回用户信息结构体
       失败返回NULL 并置位错误码
        struct passwd {
               char   *pw_name;       /* username */
               char   *pw_passwd;     /* user password */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* user information */
               char   *pw_dir;        /* home directory */
               char   *pw_shell;      /* shell program */
           };       

getgrgid()

#include <sys/types.h>
#include <grp.h>

struct group *getgrgid(gid_t gid);
功能: 通过gid获取对应组信息
参数:
    gid: 要获取信息gid(可以通过stat()获取gid)
    
返回值: 成功返回用户信息结构体
       失败返回NULL 并置位错误码

        struct group {
               char   *gr_name;        /* group name */
               char   *gr_passwd;      /* group password */
               gid_t   gr_gid;         /* group ID */
               char  **gr_mem;         /* NULL-terminated array of pointersto names of group members */
        };

2.操作目录相关函数

opendir()

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);
功能: 打开置顶目录文件
参数:
    name:目录路径及目录名

返回值: 成功返回目录指针
       失败NULL,置位错误码

closedir()

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);
功能: 关闭目录文件
参数:
    dirp: 目录指针
    
返回值: 成功0  失败-1,置位错误码

readdir()

#include <dirent.h>

struct dirent *readdir(DIR *dirp);
功能: 读取目录
参数:
    dirp: 目录指针
    
返回值: 成功返回目录信息结构体
       读到目录结尾返回NULL,不置位错误码
       失败返回NULL,置位错误码
       
       struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };

实例

// 显示指定目录下的所有文件名,除了隐藏文件
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>

int main(int argc, const char* argv[])
{
    // 1.校验参数
    if (argc != 2) {
        printf("input error\n");
        printf("usage: ./a.out dirname\n");
        return -1;
    }
    // 2.打开目录
    DIR* dp = opendir(argv[1]);
    if(NULL == dp){
        perror("opendir");
        return -1;
    }
    // 3.循环获取目录下文件
    struct dirent* red = NULL;
    while(red = readdir(dp)){
        if(red->d_name[0] != '.'){
            printf("%s\n", red->d_name);
        }
    }
    return 0;
}

3.进程

有道云笔记-进程

4.作业

4.1题

输入任意路径,将该路径下所有文件的详细信息显示出来,类似ls -l。

// 输入任意路径,将该路径下所有文件的详细信息显示出来,类似ls -l。
#include <dirent.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

// 获取文件权限
void file_privilege(mode_t m, char buf[10]);

// 获取文件类型
char file_type(mode_t m);

int main(int argc, const char* argv[])
{
    // 1.校验参数
    if (argc != 2) {
        printf("input error\n");
        printf("usage: ./a.out dirname\n");
        return -1;
    }
    // 2.打开目录
    DIR* dp = opendir(argv[1]);
    if (NULL == dp) {
        perror("opendir");
        return -1;
    }

    char filename[1024] = "";
    struct stat st_t; // 定义文件属性结构体
    char type; // 保存文件类型
    char privilege[10] = ""; // 保存文件权限
    struct passwd* pwd = NULL; // 保存用户信息结构体
    struct group* grp = NULL; // 保存组信息结构体
    struct tm* t = NULL; // 时间结构体
    char time[12] = ""; // 保存文件时间戳
    struct dirent* red = NULL; // 目录结构体

    // 3.循环获取目录下文件
    while (red = readdir(dp)) {
        // 4.设置文件路径
        sprintf(filename, "%s/%s", argv[1], red->d_name);
        // 5.获取文件属性信息
        if (-1 == stat(filename, &st_t)) {
            perror("stat");
            return -1;
        }
        // 6.获取文件类型
        type = file_type(st_t.st_mode);
        // 7.获取文件权限
        file_privilege(st_t.st_mode, privilege);
        // 8.获取用户信息
        pwd = getpwuid(st_t.st_uid);
        if (NULL == pwd) {
            perror("getpwuid");
            return -1;
        }
        // 9.获取组信息
        grp = getgrgid(st_t.st_gid);
        if (NULL == grp) {
            perror("getgrgid");
            return -1;
        }
        // 10.格式化文件时间戳
        t = localtime(&st_t.st_mtime);
        sprintf(time, "%02d %02d %02d:%02d", t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min);

        // 11.打印文件信息
        printf("%c%s %ld %s %s %ld %s %s\n", type, privilege, st_t.st_nlink, pwd->pw_name, grp->gr_name, st_t.st_size, time, red->d_name);
    }
    return 0;
}

void file_privilege(mode_t m, char buf[10])
{
    char per[] = "rwx";
    for (int i = 0; i < 9; i++) {
        // 循环右移,按位与
        if (m & (0400) >> i) {
            // 保存对于权限
            buf[i] = per[i % 3];
        } else {
            // 设置无权限
            buf[i] = '-';
        }
    }
}

char file_type(mode_t m)
{
    switch (m & S_IFMT) {
    case S_IFSOCK:
        return 's';
        break;
    case S_IFLNK:
        return 'l';
        break;
    case S_IFREG:
        return '-';
        break;
    case S_IFBLK:
        return 'b';
        break;
    case S_IFDIR:
        return 'd';
        break;
    case S_IFCHR:
        return 'c';
        break;
    case S_IFIFO:
        return 'p';
        break;
    }
}

4.2题

使用两个进程拷贝文件,父进程拷贝前半部分,子进程拷贝后半部分

// 使用两个进程拷贝文件,父进程拷贝前半部分,子进程拷贝后半部分
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/// @brief 初始化目标文件
/// @param destfile 目标文件路径及名字
/// @return 成功0  失败-1
int init_destfile(const char* destfile);

/// @brief 计算文件大小
/// @param filename 文件路径及名字
/// @return 成功返回文件大小  失败返回-1
int get_size_file(const char* filename);

/// @brief 拷贝文件
/// @param destfile 目标文件
/// @param srcfile 源文件
/// @param start 光标开始位置
/// @param end 光标结束位置
/// @return 成功0  失败-1
int copy_file(const char* destfile, const char* srcfile, int start, int end);

int main(int argc, const char* argv[])
{
    // 1.校验参数
    if (argc != 3) {
        printf("input error\n");
        printf("usage: ./a.out srcFileName destFileName\n");
        return -1;
    }

    // 2.初始化目标文件
    if (init_destfile(argv[2])) {
        return -1;
    }

    // 3.获取源文件大小
    int size = get_size_file(argv[1]);
    if (-1 == size) {
        return -1;
    }

    // 4.创建进程
    pid_t pd = fork();
    if (pd < 0) { // 创建失败
        perror("fork");
        return -1;
    } else if (pd > 0) { // 父进程
        // 拷贝前半部分数据
        copy_file(argv[2], argv[1], 0, size / 2);
    } else { // 子进程
        // 拷贝后半部分数据
        copy_file(argv[2], argv[1], size / 2, size - size / 2);
    }
    return 0;
}

int init_destfile(const char* destfile)
{
    // 1.打开文件
    int fd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (-1 == fd) {
        perror("init_destfile open destfile");
        return -1;
    }
    // 2.关闭文件
    close(fd);
    return 0;
}

int get_size_file(const char* filename)
{
    // 1.打开文件
    int fd = open(filename, O_RDONLY);
    if (-1 == fd) {
        perror("get_size_file open filename");
        return -1;
    }
    // 2.移动光标,计算大小
    int size = lseek(fd, 0, SEEK_END);
    // 3.关闭文件
    close(fd);
    // 4.返回大小
    return size;
}

int copy_file(const char* destfile, const char* srcfile, int start, int end)
{
    // 1.打开两个文件
    int destfd = open(destfile, O_RDWR);
    if (-1 == destfd) {
        perror("copy_file open destfile");
        return -1;
    }
    int srcfd = open(srcfile, O_RDONLY);
    if (-1 == srcfd) {
        perror("copy_file open srcfile");
        return -1;
    }

    // 2.设置光标位置
    lseek(srcfd, start, SEEK_SET);
    lseek(destfd, start, SEEK_SET);

    int ret = 0; // 保存每次读取的字节数
    int count = 0; // 保存已经读取的数据大小
    char buf[128] = ""; // 保存读取到的数据
    // 3.循环读取数据
    while (1) {
        // 4.读取数据
        ret = read(srcfd, buf, sizeof(buf));
        // 5.累加读取的数据大小
        count += ret;
        // 6.判断已经读取的数据大小是否超过end
        if (count >= end) {
            // 减去超出的数据
            write(destfd, buf, ret - (count - end));
            // 全部写完,退出循环
            break;
        }
        // 7.写入数据
        write(destfd, buf, ret);
    }
    // 8.关闭文件
    close(srcfd);
    close(destfd);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CG Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值