文件IO及目录操作

news2024/11/29 5:48:49

一、文件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;
}

运行结果:

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

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

相关文章

C#代码 串口通信晋中A2板,控制直流电机

1&#xff0c;在电脑中给晋中板中下载编译好的程序。 0x39 &#xff1a;开启电机的标识 代码&#xff1a; /********************************************************************************** **** 实验名称&#xff1a;串口通信实验 接线说明&#xff1a; 实验现象&…

NRF24L01原子HAl库学习

IRQ产生中断有低电平&#xff0c;在TxFIFI发送完收到ACk后产生&#xff0c; 在RxFIFO收到数据后也产生 达到最大重发次数也产生 工作时序&#xff0c;SCK空闲状态为0&#xff0c;CPOL0,第一个时钟沿采集数据CPHA0,SPI工作模式0 另外SPI高位先出&#xff0c;低字节先出 30个寄…

2024年秋季学期期中考试成绩查询系统-老师制作工具

随着2024年的日历逐渐翻至末尾&#xff0c;我们迎来了本年度的最后一次期中考试。对于我们这些教育工作者而言&#xff0c;这段时间无疑是充满挑战与收获的。今天&#xff0c;我要向大家推荐一个创新的工具——“易查分”&#xff0c;它将彻底革新我们传统的成绩发布流程。通过…

【瑞萨RA8D1 CPK开发板】lcd显示

1.8寸lcd使用gpio模拟spi驱动 由于板子引出的接口限制&#xff0c;故使用gpio模拟spi驱动中景园的1.8寸lcd 1.77寸液晶屏 1.8寸TFT LCD SPI TFT彩屏st7735驱动128x160高清屏-淘宝网 (taobao.com) 使用RASC 的gpio配置 根据厂家提供的驱动文件移植 #define LCD_SCLK_Clr() g…

【MySQL】CRUD增删改查操作

文章目录 CRUD简介一、Creat 新增1.单行数据全列插入2.单行数据全指定列插入3.多行数据指定列插入 二、Retrieve 检索1.全列查询 --练习阶段最简单的查询&#xff1a;&#xff08;在生产环境最好不要用&#xff01;&#xff01;&#xff09;2.指定列查询3.结果去重查询4.where条…

Tomcat部署java项目,反馈漏洞CVE-2005-4900: TLS SHA-1 安全漏洞(中危) *

根据项目反馈漏洞处理&#xff0c;修复部署SSL证书时反馈TLS1.2版本漏洞&#xff1a; 漏洞描述如下&#xff1a; 漏洞类型&#xff1a;密码学问题 漏洞描述&#xff1a; TLS &#xff08;全称 Transport Layer Security&#xff0c;安全传输层 协议&#xff09;是一套用于在两…

Qt 数据库,人脸识别

数据库 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QMainWindow> #include<QSqlDatabase> QT_BEGIN_NAMESPACE namespace Ui { class widget; } QT_END_NAMESPACEclass widget : public QMainWindow {Q_OBJECTpublic:widget(QWidget *parent nullptr);…

HCIP-HarmonyOS Application Developer 习题(九)

(多选) 1、HarmonyOS多窗口交互能力提供了以下哪几种交互方式&#xff1f; A. 全局消息通知 B.平行视界 C.悬浮窗 D.分屏 答案&#xff1a;BCD 分析&#xff1a;系统提供了悬浮窗、分屏、平行视界三种多窗口交互&#xff0c;为用户在大屏幕设备上的多任务并行、便捷的临时任务…

项目 多人对话

项目 目标 多人对话仿真平台 技术点 socketIO异常多线程集合面向对象字符串GUI&#xff08;client&#xff09;… 项目开发方式 迭代开发-敏捷开发 建立模型 C/S 客户端/服务器模型(console) 服务器 package com.ffyc.tcp.one;import java.io.IOException; import java.i…

【大模型】RMS Normalization原理及实现

1.RMS Normalization的原理 说RMS Normalization之前&#xff0c;先讲Layer Normalization 和 Batch Normalization。 BN和LN是两种常见的归一化方法。它们的目的是帮助模型训练更稳定、收敛更快。BN是在Batch维度上进行归一化&#xff0c;即对同一batch中每个特征维度的值进行…

操作系统的了解及安装

一、linux系统认识 linux是指操作系统的内核&#xff0c;ubuntu是指基于这种内核的操作系统&#xff0c;Ubuntu属于Linux的一个发行版本&#xff0c;有简易的用户界面&#xff0c;完善的包管理系统&#xff0c;Ubuntu还对大多数硬件有着良好的兼容性&#xff0c;包含最新的图形…

一文区分SSTI 和 CSTI

前言 有时&#xff0c;SSTI&#xff08;服务器端模板注入&#xff09;和 CSTI&#xff08;客户端模板注入&#xff09;可能会由于它们相似的负载语法而混淆。这种混乱可能会导致渗透测试人员浪费时间尝试实现反向 shell&#xff0c;即使payload仅限于客户端。 定义 &#x1d…

10.11 QT数据库实现学生信息的增、删、改、查

.pro文件 QT core gui sql .h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QSqlDatabase> //数据库管理类 #include <QSqlQuery> //数据库查寻类 #include <QSqlRecord> //记录类 #include <QMessage…

从数据到洞察:ChatGPT如何革新Python数据分析流程

导读&#xff1a;通过ChatGPT与Python的结合&#xff0c;数据分析流程得到了极大的优化和提升&#xff0c;从数据获取、清洗、代码生成到智能分析和可视化展示&#xff0c;每一步都变得更加高效和智能化。这不仅提高了分析的准确性和效率&#xff0c;还降低了技术门槛&#xff…

网络编程(18)——使用asio协程实现并发服务器

十八、day18 到目前为止&#xff0c;我们以及学习了单线程同步/异步服务器、多线程IOServicePool和多线程IOThreadPool模型&#xff0c;今天学习如何通过asio协程实现并发服务器。 并发服务器有以下几种好处&#xff1a; 协程比线程更轻量&#xff0c;创建和销毁协程的开销较…

【python】之socket编程(附带无偿源码)

本章内容 1、socket 2、IO多路复用 3、socketserver Socket socket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&#xff0c;对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现&#xff0c;socket即是一种特殊的文件&…

【路径规划】自主机器人的路径规划和导航

摘要 本文讨论了如何利用路径规划算法对自主机器人进行路径规划和导航。自主机器人在环境中的路径规划是通过参考路径与机器人的当前位置进行比对&#xff0c;采用纯追踪算法&#xff08;Pure Pursuit&#xff09;进行路径跟踪&#xff0c;以确保机器人沿预定路线行驶。本文通…

黑马程序员C++核心编程学习笔记

黑马程序员C核心编程学习笔记 一、内存 1.1 内存四区 C程序在执行时&#xff0c;将内存大致分为4个区域&#xff1a;代码区&#xff0c;全局区&#xff0c;栈区&#xff0c;堆区 代码区&#xff1a;存放函数体的的二进制代码&#xff0c;操作系统管理。 &#x1f535;特点&a…

从数据管理到功能优化:Vue+TS 项目实用技巧分享

引言 在项目开发过程中&#xff0c;优化用户界面和完善数据处理逻辑是提升用户体验的重要环节。本篇文章将带你一步步实现从修改项目图标、添加数据、优化日期显示&#xff0c;到新增自定义字段、调整按钮样式以及自定义按钮跳转等功能。这些操作不仅提升了项目的可视化效果&am…

双十一适合买什么?2024双十一值得入手好物推荐

即将来临的2024年双十一&#xff0c;有哪些超值宝贝会令人忍不住疯狂下单呢&#xff1f;双十一购物狂欢节&#xff0c;这个一年一度的盛大庆典&#xff0c;向来使我们这些热衷于购物的消费者们激动万分。那么&#xff0c;在今年的双十一&#xff0c;究竟有哪些商品能够成功吸引…