io进程----文件io

news2024/11/23 3:26:47

目录

一丶概念

二丶特点

三丶函数

1.打开文件 open

2.关闭文件 close

3.读取文件 read

4.写入文件 write

5.文件定位操作

标准IO和文件IO区别

四丶获取文件属性

1.stat函数

2.获取文件类型

五丶目录操作


一丶概念

        在posix(可移植操作系统接口)中定义的一组输入输出的函数

二丶特点

        1.没有缓冲机制,每次操作都会经过系统调用,效率比较低
        2.围绕文件描述符进行操作,文件描述符是非负整数,0 1 2 .......,依次分配
        3.默认打开三个文件描述符,0(标准输入),1(标准输出),2(标准错误)
        4.操作除了目录d以外任意类型的文件bc-lsp
        5.可移植性相对较差

问题:打开三个文件, 描述符分别是:3 4 5 ,关闭4以后,重新打开这个文件,描述符是几?

           答: 还是4,因为4在关闭以后就空闲下来,下次打开新文件默认分配4

问题:一个进程的文件描述符最大到几?最多能打开多少个文件描述符?最多能打开多少个文件?
           答: 一个进程的文件描述符最大到1023 (0-1023), 最多能打开1024个文件描述符, 最多能打开1021(1024-3)个文件。

三丶函数

1.打开文件 open

#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
功能:打开文件
参数:pathname:文件路径名
      flags:打开文件的方式
            O_RDONLY:只读
            O_WRONLY:只写
            O_RDWR:可读可写
            O_CREAT:创建
            O_TRUNC:清空
            O_APPEND:追加
返回值:成功:文件描述符
        失败:-1
当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限 
int open(const char *pathname, int flags, mode_t mode);
最后权限 = mode &(~umask)  
例如:指定权限为0666(8进制)
最终权限= 0666 & (~umask) = 0666 &(~0002) = 664

 666  => 110 110 110
&775     111 111 101
 664 	 110 110 100

打开文件方式对应表:

标准IO

文件IO

r

O_RDONLY
只读)

r+

O_RDWR
可读可写

w

O_WRONLY|O_CREAT|O_TRUNC
只写,不存在创建,存在清空

w+

O_RDWR|O_TRUNC|O_CREAT
可读可写,不存在则创建,存在清空

a

O_WRONLY|O_CREAT|O_APPEND
只写,不存在创建,存在则追加

a+

O_RDWR|O_CREAT|O_APPEND
可读可写,不存在创建,存在则追加

2.关闭文件 close

int close(int fd);
功能:关闭文件
参数:fd:文件描述符
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    int fd;
    //1.打开文件
    //fd = open("a.c", O_RDONLY); //r
    fd = open("a.c", O_WRONLY | O_CREAT | O_TRUNC, 0666); //w
    if (fd < 0)
    {
        perror("open err ");
        return -1;
    }
    printf("fd: %d\n", fd);

    //2.关闭文件
    close(fd);
    return 0;
}

3.读取文件 read

ssize_t read(int fd, void *buf, size_t count);
功能:从一个已打开的可读文件中读取数据
参数: fd  文件描述符
      buf  存放位置
      count  期望的个数
返回值:成功:实际读到的个数(小于期望值说明实际没这么多)
       返回0:表示读到文件结尾
       返回-1:表示出错,并设置errno号

4.写入文件 write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd   文件描述符
      buf   要写的内容
      count  期望写入字节数
返回值:成功:实际写入数据的个数
        失败  : -1
练习:文件IO实现cp功能。cp 源文件 新文件名
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    if (argc != 3)
    {
        printf("filename err");
        return -1;
    }
    int m = open(argv[1], O_RDWR);
    if (m < 0)
    {
        printf("argv[1] err");
        return -1;
    }
    int n = open(argv[2], O_CREAT||O_TRUNC|O_WRONLY,0777);
    if (n < 0)
    {
        printf("argv[2] err");
        return -1;
    }
    int buf[64];
    int i;
    while((i=read(m,buf,64))>0)//记录正确读取的个数,当读不到字符时停止读取
    {
        write(n,buf,i);//将正确读取的个数写入到n中
    }
    close(m);
    close(n);
    return 0;
}

5.文件定位操作

#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
        练习:向文件中第 10 位置后面写一个字符,在文件此时的位置,往后移动20个位置处,写一行字符串hello进去,求此时文件的长度。
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
    int n;
    n=open("test.txt",O_RDWR);
    if (n < 0)
    {
        printf("open err");
        return -1;
    }
    lseek(n,10,0);
    write(n,"a",1);
    lseek(n,20,1);
    write(n,"hello",5);
    off_t len=lseek(n,0,2);
    printf("%ld\n",len);
    return 0;
}

标准IO和文件IO区别

标准IO

文件IO

概念

在C库中定义的一组输入输出的函数

在posix中定义的一组输入输出的函数

特点

1.  有缓冲区,减少系统调用,提高效率

2.  围绕流操作,FILE*

3.  默认打开三个流:stdin\stdout\stderr

4.  只操作普通文件

1.  没有缓冲区,每次操作都引起系统调用

2.  围绕文件描述符操作

3.  默认打开三个文件描述符:0\1\2

4.  除目录外其他文件

函数

打开文件:fopen/freopen

关闭文件:fclose

读写文件:fgetc/fputc fgets/fputs fread/fwrite

文件定位:rewind/fseek/ftell

打开文件:open

关闭文件:close

读写文件:read/write

文件定位:lseek

四丶获取文件属性

1.stat函数

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

int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数:  path:文件路径名
       buf:保存文件属性信息的结构体
返回值:成功:0
      失败:-1

struct stat {
        ino_t     st_ino;     /* inode号 ls -il */     
        mode_t    st_mode;    /* 文件类型和权限 */
        nlink_t   st_nlink;   /* 硬链接数 */
        uid_t     st_uid;     /* 用户ID */
        gid_t     st_gid;     /* 组ID */
        off_t     st_size;    /* 大小 */
        time_t    st_atime;   /* 最后访问时间 */
        time_t    st_mtime;   /* 最后修改时间 */
        time_t    st_ctime;   /* 最后状态改变时间 */
    };

文件权限和类型需要通过位操作获取:

st_mode 主要包含了 3 部分信息:
a. 15bit ~ 12bit 保存文件类型
b. 11bit ~ 9bit 保存执行文件时设置的信息(不用管)
c. 8bit ~ 0bit 保存文件访问权限

2.获取文件类型

        S_IFMT是一个掩码,它的值是0170000(注意这里用的是八进制前缀为0,二进制0b001111000000000000), 可以用来把st_mode位与上掩码过滤提取出表示的文件类型的那四位(15bit~12bit位),也就是这四位原样获取其他位清零。

        这四位可以表示0b0000~0b1111(八进制表示:001~014)七个值,每个值分别对应不同的文件类型:套接字文件、符号链接文件、普通文件、块设备、目录、字符设备、管道。

        判断一个文件是不是普通文件,首先通过掩码S_IFMT把其他无关的部分置0,再与表示普通文件的数值比较,从而判断这是否是一个普通文件:

或者用switch

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    struct stat *st = (struct stat *)malloc(sizeof(struct stat));
    if (stat("0.c", st) != 0)
    {
        printf("stat err\n");
        return -1;
    }
    printf("idode:%ld\n", st->st_ino);
    printf("nlink:%ld\n", st->st_nlink);
    printf("size:%ld\n", st->st_size);
    printf("mode:%#o\n", st->st_mode);
    if (st->st_mode & __S_IFMT == __S_IFDIR)
        printf("目录\n");
    if (st->st_mode & __S_IFMT == __S_IFREG)
        printf("普通文件\n");
    for (int i = 8; i >= 0; i--)
    {
        if (st->st_mode & (1 << i))
        {
            switch (i % 3)
            {
            case 2:
                printf("r");
                break;
            case 1:
                printf("w");
                break;
            case 0:
                printf("x");
                break;
            }
        }
        else
            printf("-");
    }
    printf("\n");
    return 0;
}

五丶目录操作

        围绕着目录流进行操作,DIR *
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
功能:获得目录流
参数:要打开的目录
返回值:成功:目录流
       失败:NULL

struct dirent *readdir(DIR *dirp);
功能:读目录
参数:要读的目录流
返回值:成功:读到的信息    
      失败或读到目录结尾:NULL
返回值为结构体,该结构体成员为描述该目录下的文件信息

struct dirent {
        ino_t   d_ino;               /* 索引节点号*/
        off_t   d_off;               /*在目录文件中的偏移*/
        unsigned short d_reclen;    /* 文件名长度*/
        unsigned char  d_type;      /* 文件类型 */
        char    d_name[256];       /* 文件名 */
};

int closedir(DIR *dirp);
功能:关闭目录
参数:dirp:目录流

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

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

相关文章

STC89C52 定时器浅谈

文章目录 1、定时器1.1 定时器简介1.2 定时器构成1.2.1 系统时钟1.2.2 计数单元1.2.3 中断系统 1.2 定时器0/1的相关寄存器1.2.1 TMOD1.2.2 TCON 1.3 初始化定时器0 1、定时器 1.1 定时器简介 定时器&#xff0c;又称为计数器&#xff0c;是51单片机的内部资源&#xff0c;即…

16、CPU缓存架构

CPU缓存架构 CPU缓存架构详解CPU高速缓存概念CPU多核缓存架构CPU多核缓存架构缓存一致性问题分析 CPU缓存架构缓存一致性的解决方案缓存一致性协议实现原理总线窥探工作原理窥探协议类型 缓存一致性协议MESI协议 伪共享的问题linux下查看Cache Line大小避免伪共享方案 CPU缓存架…

netty编程之实现HTTP服务

写在前面 http是应用层协议&#xff0c;是我们日常开发中直接用到最多的协议了。本文来看下通过netty如何实现。 1&#xff1a;程序 netty不仅仅提供了String相关的编解码器&#xff0c;还贴心的提供了http相关的编码器和解码器&#xff0c;直接拿来用就行了&#xff0c;所以…

【3.3】贪心算法-解分发糖果

一、题目 老师想给孩子们分发糖果&#xff0c;有N 个孩子站成了一条直线&#xff0c;老师会根据每个孩子的表现&#xff0c;预先给他们评分。 你需要按照以下要求&#xff0c;帮助老师给这些孩子分发糖果&#xff1a; 1&#xff09;每个孩子至少分配到1 个糖果。 2&#xff…

apache经典模型和nginx参数配置

Apache 几个经典的 Web 服务端 ①Apache prefork 模型 ● 预派生模式&#xff0c;有一个主控制进程&#xff0c;然后生成多个子进程&#xff0c;使用select模型&#xff0c;最大并发 1024 ● 每个子进程有一个独立的线程响应用户请求 ● 相对比较占用内存&#xf…

Cyberchef实用功能之-模拟沙箱的文件静态分析能力

本文将介绍如何使用cyberchef 提取文件的重要元数据的信息&#xff0c;根据自己的需求实现沙箱中的静态文件的分析能力。 在网络安全日常的运营&#xff0c;护网行动&#xff0c;重保活动的过程中&#xff0c;样本的分析是一个重要的过程&#xff0c;这些可疑或者恶意的样本的…

Beyond Compare忽略特定格式文本

1 问题背景&#xff1a; 文本对比时忽略某些文本。比如有些生成的文件需要做差异对比&#xff0c;除了内容有差异外&#xff0c;自动生成的ID也不同&#xff0c;想忽略这些ID。特别是文件内容比较多的时候。 如上图&#xff0c;其中UUID“*”的部分我想忽略。 方法&#xff1…

微信开放平台应用签名MD5

可以使用JS转换一下 一、在任一网页 右键 检查 打开调试 二、把字母转换成小写&#xff0c;去除&#xff08;:&#xff09; MD5 应用签名示例 "70:71:5F:CA:AE:E5:B1:01:30:11:8F".toLowerCase().replace(/:/g, "") 70715fcaaee5b10130118f 就是要填写…

我们为什么推出数据模型

调用接口之前&#xff0c;要写大量的字段校验代码&#xff1f; 需要关联读写多张表的数据&#xff0c;难以写出复杂的数据库语法&#xff1f; 不仅需要开发核心的业务逻辑&#xff0c;还需要加班搭建CMS和数据管理页面&#xff1f; 数据不止放在云开发&#xff0c;还需要查询…

ctfhub-web-基础认证

HTTP协议&#xff1a;什么是HTTP基本认证_网易订阅 https://zhuanlan.zhihu.com/p/64584734 弹框输入密码账号bp抓包&#xff0c;发现了Authorization&#xff1a;后面有一串BASE64的编码(输入的密码) 账号默认是admin&#xff0c;抓包后是basic 把抓到的包发送到爆破模块i…

MySql【约束】

约束 1.1 约束 是什么? 约束,即限制,就是通过设置约束,可以限制对数据表数据的插入,删除,更新 怎么做? 约束设置的语法,大部分是 create table 表名( 字段 数据类型(长度) 约束, 字段 数据类型(长度) 约束 ); 另外一种是建表后,使用alter语句修改表添加约束 1.1 数据类型 其实…

人社大赛算法赛题解题思路分享+第五名

关联比赛: [国家社保]全国社会保险大数据应用创新大赛 赛题背景分析及理解 本次比赛&#xff0c;“精准社保”的赛题为“基本医疗保险医疗服务智能监控”&#xff0c;由参赛队完成数据算法模型的开发设计&#xff0c;实现对各类医疗保险基金欺诈违规行为的准确识别。 在进行了…

AI工业ros机械臂

1、基本介绍 该产品是一款面向于人工智能、机器人工程等专业的实验平台&#xff0c;能够学习基于人工智能技术的智能机器臂相关知识。主要由工业六轴机械臂、机械臂控制器、边缘计算主机、安全防护工作台四部分构成。该产品可完成的课程&#xff1a;机器视觉、机器人操作系统RO…

Stable Diffusion 使用详解(10)--- 场景立体字

目录 背景 复刻立体雏形 Lora 模型 参数设置与controlnet 出图效果 融入图片 提取 合成 背景 虽然都是字&#xff0c;带场景的立体字和上一节讲的做法不太一样。一般来说&#xff0c;一般这种带字体的场景字现阶段都是Lora模型居多&#xff0c;Lora 属于轻量级模型&…

linux系统中USB模块基本原理分析

大家好,今天主要给大家分享一下,USB设备的发展历程。 第一:USB发展变化 随着时代的发展,USB模块也随之不断的升级。 USB1.1:规范了USB低全速传输; USB2.0:规范了USB高速传输,采用NRZI(反向不归零)编码(NRZI采用8bit编码方式),位填充(在数据进行NRZI编码前…

每日一练-threejs实现三维动态热力图

前言&#xff1a;学习自用Three.js搞个炫酷热力山丘图&#xff0c;作者讲解的十分详细&#xff0c;在这里不再过多赘述&#xff0c;直接上代码&#xff01; <template><div class"map" ref"map"></div> </template><script set…

亿发工单管理系统助力五金行业智造升级:高效生产新篇章

在五金制造行业&#xff0c;效率和质量决定了企业的竞争力。五金厂通过引入先进的工单管理系统&#xff0c;成功实现了从传统制造向智能制造的转型。今天&#xff0c;我们将带您深入了解这场变革背后的力量&#xff0c;揭示工单管理系统如何在五金工厂的各个环节中发挥重要作用…

Redis的哨兵(高可用)

实验环境&#xff1a;用一主两从来实现Redis的高可用架构。 一、Redis哨兵 Sentinel 进程是用于监控redis集群中Master主服务器工作的状态&#xff0c;在Master主服务器发生故障的时候&#xff0c; 可以实现Master和Slave服务器的切换&#xff0c;保证系统的高可用&#xff0c…

java一键生成数据库说明文档html格式

要验收项目了&#xff0c;要写数据库文档&#xff0c;一大堆表太费劲了&#xff0c;直接生成一个吧&#xff0c;本来想用个别人的轮子&#xff0c;网上看了几个&#xff0c;感觉效果不怎么好&#xff0c;自己动手写一个吧。抽空再把字典表补充进去就OK了 先看效果&#xff1a; …

找不到msvcp140.dll无法继续执行代码的基本解决策略,快速修复msvcp140.dll错误文件

在我们日常使用电脑的过程中&#xff0c;偶尔会遇到一些令人头疼的技术问题。其中&#xff0c;"找不到 msvcp140.dll 无法继续执行代码" 的错误提示便是许多 Windows 用户常见的难题之一。这条错误消息通常在尝试启动某些程序时出现&#xff0c;指出系统缺少一个关键…