文件IO及目录操作

一、文件IO

1.1 close函数(关闭文件)

#include <unistd.h>---所需头文件
int close(int fd);
功能:关闭文件
参数:
    fd:文件描述符
返回值:成功返回0,失败返回-1,置位错误码

close使用示例:

#include <my_head.h>

int main(int argc,const char *argv[]){
    int fd1,fd2,fd3;
    fd1 = open("./a.txt",O_RDONLY);//成功返回文件描述符
    fd2 = open("./b.txt",O_RDONLY);//遵循最小分配原则
    printf("fd1 = %d fd2 = %d\n",fd1,fd2);//输出3,4
    //关闭fd1再打开一个新的文件
    close(fd1);
    fd3 = open("./c.txt",O_RDONLY);
    printf("fd3 = %d\n",fd3);
    //文件描述符会重新分配,遵循最小分配原则,
    //上面关闭了fd1,原fd1文件描述符位3,fd3文件描述符变为3

    int a = 0;
    scanf("%d",&a);//正常输入
    printf("a = %d\n",a);
    //关闭标准输入
    close(0);
    scanf("%d",&a);//标准输入已经关闭,无法再次输入
    printf("a = %d\n",a);

    //close(1);
    close(stdout->_fileno);//等价于close(1);关闭标准输出
    printf("1111111\n");

    return 0;
}

运行结果:

1.2 read/write 函数的使用

#include <unistd.h>
ssize_t read(int fd,void *buf,size_t count);
功能:从fd代表的文件中读取count个字节的数据到buf中
参数:
    fd:文件描述符
    buf:保存读取到的数据的首地址
    count:要读取的字节数
返回值:成功返回读取到的字节数,读取到文件结尾返沪0,失败返回1,置位错误码

#include <unistd.h>
ssize_t write(int fd,const void *buf,size_t count);
功能:将buf中的数据写count个字节到1fd代表的文件中
参数:
    fd:文件描述符
    buf:要写入的数据的首地址
    count:要读取的字节数
返回值:成功返回写入的字节数,失败返回-1,置位错误码


read使用示例

#include <my_head.h>

int main(int argc,const char *argv[]){
    int fd = open("./a.txt",O_RDONLY);
    if(-1 == fd){
       PRINT_ERR("open a.txt error");
    }
    //从文件中读取内容
    char read_buf[32] = {0};
    int ret = 0;
    //期望读取32个字节
    ret = read(fd,read_buf,sizeof(read_buf));
    printf("1:ret = %d\n",ret);
    //实际读取的是7个字节,因为a.txt内容大小只有a字节
    
    //再次读取
    ret = read(fd,read_buf,sizeof(read_buf));
    printf("2:ret = %d\n",ret);//返回0,到了文件结尾
    close(fd);//关闭文件
    return 0;
}

运行结果:

wirte函数的使用

#include <my_head.h>

int main(int argc,const char *argv[]){
    int fd = open("./b.txt",O_RDWR);//以读写的方式打开文件
    if(-1 == fd)
        PRINT_ERR("open b.txt error");
    //向文件中写入内容,写整数
    int var1 = 0x12345678;
    int ret = 0;
    ret = write(fd,&var1,sizeof(var1));
    printf("ret = %d\n",ret);//写入成功返回写入的字节数,失败返回-1

    //从文件中读取刚才写入的数据
    lseek(fd,0,SEEK_SET);//将光标移动到文件开头
    var1 = 0;
    read(fd,&var1,sizeof(int));
    printf("var1 = %#x\n",var1);

    return 0;
}

运行结果:

练习:read/write拷贝一个文件

#include <my_head.h>

int main(int argc,const char *argv[]){
    if(3 != argc){
        printf("入参错误\n");
        printf("使用方式:./a.out srcfile dstfile\n");
        return 0;
    }
    //打开源文件和目标文件
    int srcfd,dstfd;
    srcfd = open(argv[1],O_RDONLY);
    dstfd = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);
    if(-1 == srcfd || -1 == dstfd)
        PRINT_ERR("open error");

    //循环拷贝
    char cp_buf[128]  ={0};
    int ret = 0;

    while((ret = read(srcfd,cp_buf,sizeof(cp_buf)))>0){
        write(dstfd,cp_buf,ret);
        memset(cp_buf,0,sizeof(cp_buf));
    }

    close(srcfd);
    close(dstfd);
    
    return 0;
}

运行结果:

1.3 lseek函数的使用

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd,off_t offset,int whence);
功能:偏移文件光标
参数:
    fd:文件描述符
    offset:偏移量
        <0:向前偏移
        =0:不偏移
        >0:向后偏移
    whence:偏移的基地址
        SEEK_SET:从文件开头开始偏移
        SEEK_CUR:从当前位置开始偏移
        SEEK_END:从文件结尾开始偏移
返回值:成功返回光标位置,失败返回-1,置位错误码

lseek使用示例

#include <my_head.h>

typedef struct RGB
{
    unsigned char b;
    unsigned char g;
    unsigned char r;
} rgb_t;

int main(int argc, const char *argv[])
{

    rgb_t color = {
        .b = 0,
        .g = 0,
        .r = 255,
    };
    // 1.打开图片文件
    int fd = open("./ddm.bmp",O_RDWR);
    // 2.首先要将光标偏移到像素数据前,54个字节
    int pos = 0;
    pos = lseek(fd, 54, SEEK_SET);//返回的就是当前光标的位置
    printf("当前光标的位置是%d\n",pos);
    // 3.偏移光标到要操作的像素数据前
    lseek(fd, ((631 * 1920) + 712) * 3, SEEK_CUR);
    // 开始循环写入像素数据,覆盖鼻子
    for (int j=0;j<745-631; j++)
    {
        for (int i = 0; i < (835 - 712); i++)
        {
            write(fd,&color,sizeof(color));
        }//循环结束操作了鼻子所在方框的一行
        //每次内循环结束之后,都将光标偏移到鼻子所在方框的第二行
        lseek(fd,(1920-(835 - 712))*3,SEEK_CUR);
    }

    return 0;
}

1.4 stat(获取文件属性)

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname,struct stat *statbuf);
功能:获取pathname对应文件的属性信息到statbuf中
参数:
    pathname:文件的路径和文件名
    statbuf:保存文件属性信息的结构体的首地址
返回值:成功返回0,失败返回-1,置位错误码
struct stat *statbuf结构解析:
      struct stat {
               dev_t     st_dev;         /* 文件所在磁盘的设备号 */
               ino_t     st_ino;         /* 文件的inode号 */
               mode_t    st_mode;        /* 文件的类型和权限 */
                   
               nlink_t   st_nlink;       /*文件的硬链接数,对于目录文件,是子目录的个数 */
               uid_t     st_uid;         /* 文件所属用户的uid */
               gid_t     st_gid;         /* 文件所属用户的组id */
               dev_t     st_rdev;        /* 如果是设备文件,设备ID */
               off_t     st_size;        /* 文件的大小 */
               blksize_t st_blksize;     /* 块儿大小 */
               blkcnt_t  st_blocks;      /* 块的数量*/


               struct timespec st_atim;  /* 上一次访问文件的时间 */
               struct timespec st_mtim;  /* 上次修改文件的时间 */
               struct timespec st_ctim;  /* 上次文件状态改变的时间 */
};
mode_t st_mode;解析:
                             012xxxx
(文件类型的位掩码)S_IFMT    0170000
st_mode & S_IFMT    ------->文件的权限信息
    stat(pathname,&sb);
    if((sb.st_mode & S_IFMT) == S_IFREG){
}
        S_IFSOCK 0140000    套接字文件
        S_IFLNK  0120000    链接文件
        S_IFREG  0100000    普通文件
        S_IFBLK  0040000    目录文件
        S_IFCHR  0020000    字符设备文件
        S_IFIFO  0010000    管道文件
通过宏定义的方式去判断
       S_ISREG(m)  is it a regular file?

           S_ISDIR(m)  directory?

           S_ISCHR(m)  character device?

           S_ISBLK(m)  block device?

           S_ISFIFO(m) FIFO (named pipe)?

           S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

           S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

       使用方式

           stat(pathname, &sb);
           if (S_ISREG(sb.st_mode)) {
               /* Handle regular file */
           }  
0777 & st_mode    获取到的文件的权限
0666 & 0777 == 0666

stat 函数使用示例

#include <my_head.h>

int main(int argc, const char *argv[])
{
    if (2 != argc)
    {
        printf("入参错误\n");
        printf("使用方式 ./a/out filename\n");
        return -1;
    }
    // 1.获取文件属性信息
    struct stat st;
    stat(argv[1], &st);

    // 2.打印文件信息
    printf("inode号: %ld\n", st.st_ino);
    printf("uid: %d\n", st.st_uid);
    printf("硬链接个数: %ld\n", st.st_nlink);
    printf("上次修改的时间: %ld\n", st.st_mtime);
    printf("上次访问的时间: %ld\n", st.st_atime);
    printf("上次改变文件状态的时间: %ld\n", st.st_ctime);

    switch (st.st_mode & __S_IFMT)
    { //__S_IFMT是文件类型的掩码
    case __S_IFSOCK:
        printf("%s是套接字文件\n", argv[1]);
        break;
    case __S_IFLNK:
        printf("%s是链接文件\n", argv[1]);
        break;
    case __S_IFREG:
        printf("%s是普通文件\n", argv[1]);
        break;
    case __S_IFBLK:
        printf("%s是块设备文件\n", argv[1]);
        break;
    case __S_IFDIR:
        printf("%s是目录文件\n", argv[1]);
        break;
    case __S_IFCHR:
        printf("%s是字符设备文件\n", argv[1]);
        break;
    case __S_IFIFO:
        printf("%s是管道文件文件\n", argv[1]);
        break;
    default:
        printf("未知的文件类型\n");
        break;
    }

printf("文件的权限是%#o\n",st.st_mode & 0777);

return 0;
}

运行结果:

1.5 getpwuid 和 getgrgid 函数的使用

1.5.1 函数说明

#include <sys/types.h> --- 所需头文件
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
功能:根据uid获取用户的相关信息
参数:   
    uid:用户的uid
返回值:指向用户信息结构体的指针
struct passwd{
    char *pw_name; ---- 用户名
    char *pw_passwd; ---- 用户密码
    uid_t pw_uid; ---- 用户id
    gid_t pw_gid; ---- 用户的组id
    char *pw_gecos; ---- 用户的描述信息
    char *pw_dir; ---- 用户的家目录
    char *pw_shell; ---- 默认的命令解析器
};
这个结构体中的信息的源头是/etc/passwd文件中的信息

#include <sys/types.h>
#include <grp.h>
struct group *getrgid(gid_t gid);
功能:根据gid获取用户所属组的相关信息
参数:gid
返回值:成功返回指针白村组信息的结构体指针,失败返回NULL,置位错误码
The group structure is defined in <grp.h> as follows:
struct group{
    char *gr_name; --- 组名
    char *gr_passwd; --- 组密码
    gid_t gr_gid; --- 组id
    char **gr_mem; --- 组成员
};
获取的是/etc/group中的组信息

getpwuid的使用

#include <my_head.h>

int main(int argc,const char *argv[]){
    struct passwd *pw_info;
/*getuid() 函数会返回用户的uid,这个函数总是成功*/
    uid_t uid = getuid();
    printf("当前用户的uid是%d\n",uid);
    pw_info = getpwuid(uid);//根据uid获取用户的信息
    if(NULL == pw_info){
        PRINT_ERR("getpwuid error");
    }
    printf("用户名:%s\n",pw_info->pw_name);
    printf("家目录:%s\n",pw_info->pw_dir);
    printf("用户描述信息:%s\n",pw_info->pw_gecos);
    printf("用户组id:%d\n",pw_info->pw_gid);
    printf("用户密码:%s\n",pw_info->pw_passwd);
    printf("用户的命令解析器:%s\n",pw_info->pw_shell);
    printf("用户id:%d\n",pw_info->pw_uid);

    return 0;
}

运行结果:

getgrgid的使用

#include <my_head.h>

int main(int argc,const char *argv[]){
    //获取当前用户的组id
    gid_t gid = getgid();
    printf("gid = %d\n",gid);
    struct group *gp;
    gp = getgrgid(gid);
    if(NULL == gp){
        PRINT_ERR("getgrgid error");
    }
    printf("组名是%s\n",gp->gr_name);
    printf("组id %d\n",gp->gr_gid);
    return 0;
}

运行结果:

二、目录操作

2.1 opendir() 打开目录

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

DIR *opendir(const char *name);
功能:打开name对应的目录
参数:
    name:目录的名字
返回值:成功返回指向的目录的指针,失败返回NULL置位错误码


2.2 closedir() 关闭目录

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

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

2.3 readdir() 读取目录信息

#include <dirent.h>
struct dirent *readdir(DIR *dirp);
功能:读取目录中的内容
参数:
    dirp:使用opendir获取的目录指针
返回值:成功返回一个指针,指针指向的结构体中包含了第一个文件相关的信息,如果想要获取其他文件的信息,需要反复读取
失败或者读到文件结尾,返回NULL
如果由于失败导致返回NULL,错误码会被置位
struct dirent{
    ino_t    d_ino; -- 文件的inode号
    off_t    d_off; -- 不太用关注
    unsigned short    d_reclen; -- 这条记录的长度
    unsigned char    d_type; -- 文件的类型
                      DT_BLK  块设备文件
                      DT_CHR      字符设备文件
                      DT_DIR      目录文件
                      DT_FIFO     管道文件
                      DT_LNK      链接文件
                      DT_REG      普通文件
                      DT_SOCK    套接字文件
                      DT_UNKNOWN  未知的文件类型
    char    d_name[256]; -- 文件的名字
}

2.4 目录操作的使用用例

#include <my_head.h>

int main(int argc, const char *argv[])
{
    if (argc != 2)
    {
        printf("入参错误\n");
        printf("使用方式:./a.out dirname\n");
        return -1;
    }
    // 打开目录
    DIR *dir;
    struct dirent *FileInDir;
    dir = opendir(argv[1]);
    if (NULL == dir)
        PRINT_ERR("opendir error");
    // 读取目录的内容
    while ((FileInDir = readdir(dir)) != NULL)
    {
        
        printf("读取到的文件名是%s\n", FileInDir->d_name);
        printf("文件的inode号 %ld\n", FileInDir->d_ino);
        printf("这条记录的长度 %d\n", FileInDir->d_reclen);

        switch (FileInDir->d_type)
        {
        case DT_DIR:
            printf("这是目录文件\n");
            break;
        case DT_BLK:
            printf("这是块设备文件\n");
            break;
        case DT_REG:
            printf("是普通文件\n");
            break;
        default:
            printf("位置文件类型\n");
            break;
        }
        printf("---------------------------------------\n");
    }
    closedir(dir);
    return 0;
}

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

主机加固的关键要素:服务器防病毒

在数字化浪潮中&#xff0c;网络安全已成为企业不可忽视的一环。尤其是安全运维人员&#xff0c;他们肩负着保护企业数据不受侵害的重任。MCK主机加固解决方案&#xff0c;正是为了应对这一挑战而生。 网络安全的严峻现实 不久前&#xff0c;一家知名企业因勒索病毒攻击而被迫…

二分查找一>0~n-1中缺失的数字(点名)

1.题目&#xff1a; 2.解析&#xff1a;方法一&#xff1a;用哈希表&#xff1a;记录存在的数字&#xff0c;找到哈希表为空的数字输出 Set<Integer> set new HashSet<>();for(int x : records) set.add(x);for(int i 0; i < set.size(); i){if(!set.contain…

Linux系列-Linux的常见指令

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” Linux基本指令 ls指令 语法&#xff1a;ls 【选项】【目录或文件】 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件&#xff0c;对于文件&#xf…

【GO基础学习】环境安装到基础语法(1)

文章目录 环境安装GoLand 安装GO基础GO特点类型和函数Init函数和main函数GO命令下划线变量和常量数组切片Slice 引用 环境安装 下载地址&#xff1a;https://www.golangroadmap.com/ 安装目录文件说明&#xff1a; api&#xff1a;每个版本的 api 变更差异。 bin&#xff1…

基于SpringBoot+Vue的船舶监造系统(带1w+文档)

基于SpringBootVue的船舶监造系统(带1w文档) 基于SpringBootVue的船舶监造系统(带1w文档) 大概在20世纪90年代&#xff0c;我国才开始研发船舶监造系统&#xff0c;与一些发达国家相比&#xff0c;系统研发起步比较晚。当时的计算机技术刚开始发展起来&#xff0c;国家经济力量…

Map的实现类:HashMap

在API获取HsahMap类的全部信息 实例代码&#xff1a;创建一个Student类和Demo02 package com.map;public class Student {private String name;private int stuNo;public Student(String name, int stuNo) {this.name name;this.stuNo stuNo;}public String getName() {retu…

从零开始构建:Python自定义脚本自动化你的日常任务

从零开始构建&#xff1a;Python自定义脚本自动化你的日常任务 Python 作为一种简洁且功能强大的编程语言&#xff0c;被广泛应用于各种自动化任务中。通过编写 Python 脚本&#xff0c;你可以轻松地将日常重复性工作自动化&#xff0c;例如文件操作、数据处理、网络爬虫、系统…

C++ | Leetcode C++题解之第457题环形数组是否存在循环

题目&#xff1a; 题解&#xff1a; class Solution { public:bool circularArrayLoop(vector<int>& nums) {int n nums.size();auto next [&](int cur) {return ((cur nums[cur]) % n n) % n; // 保证返回值在 [0,n) 中};for (int i 0; i < n; i) {if …

STM32 407 RS485通信实现数据收发【我的创作纪念日】

1. 前言 本例中的485驱动&#xff0c;基于标准库编写&#xff0c;不是HAL库&#xff0c;请大家注意。 最近搞嵌入式程序&#xff0c;踩了不少坑&#xff0c;这里统一记录一下。 2. 收获 1.串口通信&#xff0c;数据是一个字节一个字节的发送&#xff0c;对方收到的数据是放在…

github学生认证(Github Copilot)

今天想配置一下Github Copilot&#xff0c;认证学生可以免费使用一年&#xff0c;认证过程中因为各种原因折腾了好久&#xff0c;记录一下解决方法供大家参考。 p.s.本文章只针对Github学生认证部分遇到的问题及解决方法&#xff0c;不包括配置copilot的全部流程~ 1、准备工作…

无图化加速!MemFusionMap提出时序重叠热图策略,在线建图mAP暴涨5.4%!

导读&#xff1a; HDMap对于自动驾驶系统至关重要&#xff0c;因为它可以为规划提供了精细的道路信息。尽管现有的单帧输入方法在在线矢量化高精地图构建方面取得了不错的成绩&#xff0c;但在处理复杂场景和遮挡时仍然存在挑战。为了解决这些问题&#xff0c;作者提出了 MemFu…

AWR1642+DCA1000采集ADC数据并解析

文章同步发布在CSDN和公众号(雷达原理与系统),后续文章中出现的资料,参考文档等都会放在GitHub仓库,欢迎fork和star。 0. 序言 为什么要先将采集ADC数据呢?因为ADC数据是信号处理的输入,是后续理解信号处理手段的基础。当然这里也可以采用仿真信号,但我的想法是单独出…

SQL第13课——创建高级联结

本课讲另外一些联结&#xff08;含义和使用方法&#xff09;&#xff0c;如何使用表别名&#xff0c;如何对被联结的表使用聚集函数。 13.1 使用表别名 第7课中使用别名引用被检索的表列&#xff0c;给列起别名的语法如下&#xff1a; SQL除了可以对列名和计算字段使用别名&a…

聚类分析 | IPOA优化FCM模糊C均值聚类优化算法

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 (多图聚类)IPOA优化FCM模糊C均值聚类优化算法&#xff0c;matlab代码&#xff0c;超多图 基于改进的鹈鹕优化算法&#xff08;IPOA&#xff09;优化FCM模糊C均值聚类优化&#xff0c;matlab代码&#xff0c;直接运行…

HTB:Preignition[WriteUP]

连接至HTB服务器并启动靶机 靶机IP&#xff1a;10.129.157.49 分配IP&#xff1a;10.10.16.12 1.Directory Brute-forcing is a technique used to check a lot of paths on a web server to find hidden pages. Which is another name for this? (i) Local File Inclusion, (…

窗口售票系统1.0版本

本窗口售票系统实现了三个售票窗口的随机售票&#xff0c;实现随机到某一个窗口买票&#xff0c;总票余量都会减少&#xff0c;即三个窗口共享同一个票余量。若票余量小于一次性购票量&#xff0c;则提示报错&#xff1b;若车票售罄&#xff0c;则代码结束运行。 代码实现&…

用户和组管理

用户管理 用户管理包括创建用户、修改用户属性、删除用户等操作。 创建用户 使用 useradd 命令可以创建新用户。 格式&#xff1a;useradd [选项] username 步骤1&#xff1a;创建新用户 useradd tom 步骤 2: 设置用户密码 新用户创建后&#xff0c;需要设置一个密码才能…

需求8——通过一个小需求来体会AI如何帮助改bug

这篇文章&#xff0c;我们通过一个简单的例子来说明&#xff0c;平时在写需求的时候&#xff0c;我们可以在什么时候用AI来帮助我们写代码。 首先来看一下这个需求&#xff1a;系统中某个用户使用的时候出现了bug&#xff0c;通过手机建立临时任务报错&#xff0c;没有办法新增…

ElasticSearch备考 -- Update by query Reindex

一、题目 有个索引task&#xff0c;里面的文档长这样 现在需要添加一个字段all&#xff0c;这个字段的值是以下 a、b、c、d字段的值连在一起 二、思考 需要把四个字段拼接到一起&#xff0c;组成一个新的字段&#xff0c;这个就需要脚本&#xff0c; 这里有两种方案&#xff…

ES(Elasticsearch)SSL集群部署

8.x后ES不在需要自行准备JDK环境&#xff0c;部署的服务包含ES、Kibana、Logstash&#xff0c;使用二进制方式部署&#xff0c;为了提高安全性&#xff0c;加密logstash、kibana及其他客户端到ES间的通信。 1、准备工作 1.1、 es无法使用root用户启动 useradd -m -s /bin/bas…