当前位置: 首页 > java >正文

华清远见25072班I/O学习day2

重点内容:

模块化读写(fread/fwrite)

        size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

        功能:从stream指向的文件中读取nmemb项数据,每一项的大小为size 并且放入ptr指向的容器中

        参数1:存放数据的容器,可以是任意类型的指针

        参数2:每一项的大小

        参数3:读取的总项数

        参数4:文件指针

        返回值:成功返回读取的项数,失败或者文件结束返回一个小于项数的值         

        注意:fread不区分到底是因为文件结束还是因为错误导致的结束,可以使用feof和ferror来判断

        size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

        功能:将ptr指向的容器中的内容,每项为size大小的nmemb项数据,写入到stream指向的文件中

        参数1:要写入的数据起始地址

        参数2:每一项的大小

        参数3:要写入的项数

        参数4:文件指针

        返回值:成功返回写入的项数,失败或者文件结束返回一个小于项数的值

有关文件指针光标的操作(fseek/ftell/rewind)

        int fseek(FILE *stream, long offset, int whence);

        功能:将给定的文件指针的光标进行重新定位

        参数1:文件指针

        参数2:偏移量(以字节为单位) >0:表示从给定的基准向后偏移 =0:表示在基准处不偏移 <0:从基准处向前偏移

        参数3:基准 SEEK_SET:文件开始位置 SEEK_CUR:光标当前位置 SEEK_END:文件结尾位置

        返回值:成功返回0,失败返回-1并置位错误码

        long ftell(FILE *stream);

        功能:求出现在文件指针光标所在位置(以字节为单位)

        参数:文件指针

        返回值:光标目前所在位置

eg:求一个文件的大小 1、将光标先定位到结尾:fseek(fp, 0, SEEK_END); 2、此时使用ftell的返回值,就是文件的大小:ftell(fp);

        void rewind(FILE *stream);

         功能:将文件光标定位到开始位置             等同于:fseek(fp, 0, SEEK_SET);

        参数:文件指针

        返回值:无

有关缓冲区的问题

        1.对于标准IO而言,分为三种缓冲区:

                全缓存、行缓存、不缓存

        2.全缓存:对应的是用户打开的文件指针:fp 其大小为4096字节

        行缓存:对应的是stdin和stdout,其大小为1024字节

        无缓冲:对应的是stderr,其大小为0字节

        3.缓冲区的刷新时机

                1、行缓存

                        1、遇到\n会刷新

                        2、当使用fflush刷新时,会刷新缓冲区

                        3、当程序结束时会刷新缓冲区

                        4、当使用exit退出进程时,会刷新标准io缓冲区

                        5、当输入输出发生切换时会刷新缓冲区

                        6、当缓冲区满了后,再向缓冲区中放数据时,会刷新该缓冲区

                2、全缓存

                        1、当使用fflush刷新时,会刷新缓冲区

                        2、当程序结束时会刷新缓冲区

                        3、当使用exit退出进程时,会刷新标准io缓冲区

                        4、当输入输出发生切换时会刷新缓冲区

                        5、当缓冲区满了后,再向缓冲区中放数据时,会刷新该缓冲区

                3、没有条件,放入立即刷新

有关错误码的问题

        1.错误码是调用内核提供的函数时,如果调用出错,那么内核空间会向用户空间反馈一个错误信息

        2.错误信息千奇百怪,并且是字符串内容,为了方便起见,给这些错误信息,进行编号

        3.如果,内核空间函数调用出问题时,只需要反馈错误编号即可,这个错误编号就叫做错误码

        4.常见错误码:可以通过指令 vi -t EIO 查看

文件IO:

        文件IO是指用户直接调用内核提供的函数来进行IO操作,但是标准IO使用的是文件指针完成,文件IO使用的是文件描述符来实现

文件描述符

        1.文件描述符是内核用来跟外部文件设备操作的一个非负整数

        2.每一个文件描述符对应一个操作的文件

        3.当一个程序启动后,系统默认打开三个特殊的文件描述符,分别是0号(标准输入stdin)、1号(标准输出)和2号(标准出错)

        4.文件描述符的分配原则是:最小未使用原则

        5.默认情况下,一个进程能够打开的文件描述符的个数为1024个,也就是0--1023

打开文件open

        int open(const char *pathname, int flags);

        int open(const char *pathname, int flags, mode_t mode);

        功能:使用系统调用,打开给定pathname对应的文件,并返回该文件对应的文件描述符

        参数1:要被打开的文件

        参数2:打开模式

                1、必须包含以下三个中的一个

                        O_RDONLY: 只读的形式打开文件

                        O_WRONLY:只写的形式打开文件

                        O_RDWR:读写的形式打开文件

                2、下面的可以包含也可以不包含,根据需要而定,所有标识通过位或连接

                        O_CREAT:如果文件不存在,则创建文件,注意,如果参数2中包含该标识, 则必须提供参数3,为文件的操作权限

                        O_TRUNC:清空文件内容

                        O_APPEND:追加形式

                        O_EXCL:确保创建新文件成功,如果文件已经存在,则报错,错误码为EEXIST

        参数3:文件操作权限。注意:最终的文件权限,是由给定的权限跟默认掩码取反后取位与运算得到

        运算:mode & (~umask)                 umak取决于终端

        一般情况下:文件夹的权限最大为:0775 普通文件的权限:0664

        返回值:成功返回打开的文件对应的文件描述符(最小未分配原则),失败返回-1并置位错误码

        标准IO打开文件模式对应的操作位

关闭文件close

        int close(int fd);

        功能:关闭指定的文件描述符

        参数:文件描述符

        返回值:成功返回0,失败返回-1并置位错误码

数据读写(read、write)

        ssize_t read(int fd, void *buf, size_t count);

        功能:从fd文件描述符中读取count个字节的数据,并存放到buf指向的容器中

        参数1:文件描述符

        参数2:存放数据的容器起始地址

        参数3:要读取数据的大小

        返回值:成功返回读取的字节个数,失败返回-1并置位错误码

        ssize_t write(int fd, const void *buf, size_t count);

        功能:向fd文件描述符标识的文件中写入以buf作为起始地址的count个数据

        参数1:文件描述符

        参数2:要写入数据的容器起始地址

        参数3:要写入数据的大小

        返回值:成功返回写入的字节个数,失败返回-1并置位错误码

光标偏移(lseek)

        off_t lseek(int fd, off_t offset, int whence);

        功能:偏移fd文件描述符的光标

        参数1:文件描述符

        参数2:偏移量(以字节为单位)

                >0:表示从给定的基准向后偏移

                =0:表示在基准处不偏移

                <0:从基准处向前偏移

        参数3:基准

                SEEK_SET:文件开始位置

                SEEK_CUR:光标当前位置

                SEEK_END:文件结尾位置

        返回值:成功返回光标当前位置,失败返回(off_t)-1并置位错误码


作业:

1> 使用fread、fwrite实现两个文件的拷贝

程序源码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
FILE *fp=NULL;
FILE *fp1=NULL;
//从文件中读取数据
if((fp = fopen("./wcg.txt", "r")) == NULL)
{
printf("文件打开失败\n");
return -1;
}
if((fp1 = fopen("./wcgcope.txt", "w")) == NULL)
{
printf("文件打开失败\n");
return -1;
}
//将文件中的数据读取出来
char buf[128] = "";
while(1)
{
int res = fread(buf, 1, sizeof(buf), fp);
if(res < 128)
{
//判断是因为文件结束还是因为错误
if(feof(fp))
{
//printf("buf=%s\n", buf);
//将读取的数据全部写到新的文件中
fwrite(buf, res, 1, fp1);
break;           //因为文件结束
}
if(ferror(fp))
{
printf("fread操作失败\n");
return -1;
}
}
//将读取的数据写到新的文件中
fwrite(buf, res, 1, fp1);
}
//关闭文件
fclose(fp);
fclose(fp1);
return 0;
}

2> 使用fread、fwrite实现将一个文件中的所有数字写入到另一个新文件中

程序源码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//定义函数用于筛选数字
void num(char *p,char *q,int len)
{
int j=0;
for(int i=0;i<len;i++)
{
if(p[i]>='0'&&p[i]<='9')
{
q[j++]=p[i];
}
}
q[j]='\0';
}
int main(int argc, const char *argv[])
{
FILE *fp=NULL;
FILE *fp1=NULL;
//从文件中读取数据
if((fp = fopen("./wcg.txt", "r")) == NULL)
{
printf("文件打开失败\n");
return -1;
}
if((fp1 = fopen("./wcgcope1.txt", "w")) == NULL)
{
printf("文件打开失败\n");
return -1;
}
//将文件中的数据读取出来
char buf[128] = "";
while(1)
{
char arr[128]="";
int res = fread(buf, 1, sizeof(buf), fp);
if(res < 128)
{
//判断是因为文件结束还是因为错误
if(feof(fp))
{
//将读取的数据全部写到新的文件中
num(buf,arr,res);
fwrite(arr,1,strlen(arr),fp1);
break;           //因为文件结束
}
if(ferror(fp))
{
printf("fread操作失败\n");
return -1;
}
}
//将读取的数据写到新的文件中
num(buf,arr,res);
fwrite(arr,1,strlen(arr),fp1);
}
//关闭文件
fclose(fp);
fclose(fp1);
return 0;
}

3> 使用文件IO完成两个文件的拷贝

程序源码:

#include <25072head.h>
int main(int argc, const char *argv[])
{
//1、创建并打开一个文件
int fd = -1;
if((fd = open("./tt.txt", O_RDWR|O_CREAT|O_TRUNC, 0664)) == -1)
{
perror("open error");
return -1;
}
int fd1=-1;
if((fd1 = open("./ttcope.txt", O_RDWR|O_CREAT|O_TRUNC, 0664)) == -1)
{
perror("open error");
return -1;
}

    printf("fd = %d\n", fd);         
//向文件中写入数据
char buf[128] = "";
while(1)
{
//从终端获取数据
int res = read(0, buf, sizeof(buf));
if(res == 1)
{
break;
}
//将数据写入到fd指向的文件中
write(fd, buf, res);
}
//从文件中读取数据
lseek(fd,0,SEEK_SET);
char rbuf[128] = "";
int res = read(fd, rbuf, sizeof(rbuf));     //从文件中读数据
//将数据写到终端上
write(fd1, rbuf, res);
//关闭文件
close(fd);
return 0;
}

4> 自己总结标准IO和文件IO的区别与联系

        标准IO:代码和程序员之间的数据交互        

        文件IO:代码和文件系统之间的数据交互

                1.文件IO没有缓冲区,标准IO函数存在缓冲区

                2.标准IO函数的读取速度快于文件IO函数

                3,标准IO函数本质上就是文件IO的二次封装,标准IO=文件IO+缓冲区

                4.文件IO可以直接和内核交互,标准IO不可以直接和内核交互,标准IO函数只可以访问普通文件,但是文件IO函数可以访问任意的特殊文件(管道,套接字)

                5.文件IO属于系统文件,依赖于操作系统,可以移植性差

                6.标准IO函数属于库文件,可以在不同的操作系统中使用,可移植性强

                7.文件IO遵循POIX标准,标准IO函数满足ANSI标准

                8.文件IO函数操作文件需要借助于文件描述符

                9.标准IO函数操作文件需要借助于流指针

5> 思维导图

6> 牛客网刷题 >= 26

http://www.xdnf.cn/news/19604.html

相关文章:

  • 继承体系中的隐藏机制解析(继承中的作用域)
  • MongoDB主从切换实战:如何让指定从库“精准”升级为主库?保姆级教程!
  • 基于单片机智能家居语音控制系统
  • 如何在VS Code远程连接Xshell使用
  • Linux - Redis离线安装(安装包的方式安装Redis)
  • 从Redisson分布式锁看锁的设计思路
  • IPC 进程间通信 interprocess communicate
  • 企业微信AI落地:如何选择企业微信服务商?
  • Axios拦截器:前端通信的交通警察[特殊字符]
  • 搭载AX650N高能效比智能视觉芯片——AX2050系列边缘计算盒,可应用在智慧安防交通仓储教育,人脸识别,明厨亮灶,安全生产,智能机器人等
  • table表格字段明细展示
  • 不透明指针
  • 【iOS】折叠cell
  • 《青衣剑客 · Claude》连载
  • 总线矩阵的原理
  • 如何将多个Excel报表合并为一个汇总文件?
  • N32G43x Bootloader 中 ENV 区的管理与实现
  • 前缀和(优化算法)
  • ClickHouse常见问题——ClickHouseKeeper配置listen_host后不生效
  • 面试 TOP101 动态规划专题题解汇总Java版(BM62 —— BM82)
  • 二、SVN基础命令速查表
  • leetcode 1792. 最大平均通过率 中等
  • 通过 select into outfile / load data infile 进行数据导入导出学习笔记
  • 开源项目_金融分析工具TradingAgents
  • 01数据结构-红黑树
  • python 数据类型【python进阶一】
  • java设计模式一、单例模式
  • 【K8s】整体认识K8s之Configmap、Secret/ResourceQuota资源配额/访问控制
  • Linux应用开发-windows,linux环境下相关工具
  • Adobe Illustrator 2025最新破解教程下载安装教程,Illustrator2025最新版下载