I/O

input&output,是一切实现的基础。如果没有i/o,我们在linux上编译的代码将只会在终端出现,将当前进程关闭后,数据无法保留。

标准IO与系统调用(文件)IO的区别



系统IO是操作系统封装的一些函数如open,close,printf,malloc等API函数构成,
简单来说标准IO由第三方规定,结合系统IO重新规划了一套C库函数,这些函数也是由系统IO封装实现的,但是在多平台下可以使用。

标准IO

不仅在 UNIX 系统,在很多操作系统上都实现了标准 I/O 库
标准 I/O 库由 ANSI C 标准说明
标准 I/O 库处理很多细节,如缓存分配、以优化长度执行 I/O 等,这样使用户不必关心如何选择合适的块长度
标准 I/O 在系统调用函数基础上构造的,它便于用户使用标准 I/O 库及其头文件 stdio.h 为底层 I/O 系统调用提供了一个通用的接口。

缓冲区

库函数的本质还是系统调用,只不过库函数多了缓冲区,缓冲区用于减少系统调用的次数
从而提高效率
只要调用标准 IO 相关的函数,都会创建缓冲区
标准 IO 既然有缓冲区来减少系统调用的次数,那什么时候会调用调用呢?只有当刷新缓冲
区的时候才会调用系统调用

文件指针

对于标准 IO 而言,任何一个打开的文件都具有很多属性,这些属性都保存在一个结构体里
面,这个结构体的类型是 FILE 类型,所以如果要操作文件,一般都需要一个 FILE 类型的指
针变量保存文件信息,所以对这个指针变量的操作就是对文件的操作,所以这个结构体指
针变量称之为文件指针,也称之为流指针
流(stream)
定义:所有的 I/O 操作仅是简单的从程序移进或者移出,这种字节流,就称为流。
分类:文本流/二进制流

****FILE 结构体: **********************************************************
typedef struct _IO_FILE FILE;

注意事项:
当一个程序运行的时候,系统会自动给当前程序分配三个文件指针,这三个文件指针
主要用于对终端的操作
stdin 标准输入流指针 从终端读取数据时要使用这个流指针
stdout 标准输出流指针 向终端写数据时要使用这个流指针
stderr 标准出错输出流指针 如果想终端写出错的信息,使用这个流指针

相关函数

  1. fopen() 打开或者创建文件,返回一个文件指针
  2. fclose() 关闭文件
  3. fprintf() 将参数写入文件
  4. fputc() 向文件写入字符
  5. fgetc() 从文件中读取一个字符
  6. fputs() 向文件写入字符串
  7. fgets() 从文件中读取字符串
  8. fread() 读取文件内容(任意类型的数据)
  9. fwrite() 向文件写内容
  10. fseek()/rewind()/ftell() 设置文件指针位置
  11. long ftell()(FILE*stream)
  12. void rewind(FILE*stream) 相当于fseek(fp,0,SEEK_SET)
  13. time() 得出从1970.1.1零点开始到当下的时间

函数使用

1.fopen()

头文件

:#include<stdio.h>

使用实例:

FILE *fopen(const char *pathname, const char *mode);
打开或创建文件

#include<stdio.h>
#include<errno.h>
int main()
{FILE *fp;//文件不存在就打开失败  并且设置错误码fp = fopen("file.txt","r");//“r”表示以只读方式打开,定位到文件起始位置;if(fp==NULL){perror("fopen");printf("errno = %d\n",errno);return -1;}return 0;
}

r 以只读的方式打开文件,定位到文件起始位置
r+ 以读写的方式打开文件,定位到文件起始位置
w 以只写的方式打开文件,如果文件存在则清空,如果文件不存在则创建,定位到文
件起始位置
w+ 以读写的方式打开文件,如果文件存在则清空,如果文件不存在则创建,定位到文
件起始位置
a 以只写的方式打开文件,如果文件存在则追加,如果文件不存在则创建,定位到文
件末尾位置
a+ 以读写的方式打开文件,如果文件存在则追加,如果文件不存在则创建,定位到文
件末尾位置

返回值:

成功:返回一个文件指针;
失败:NULL,并设置错误码;

2.fclose()

头文件:
#include<stdio.h>
使用实例:

int fclose(FILE *stream);
关闭一个文件指针,关闭后无法通过文件指针对此文件进行操作

#include<stdio.h>
#include<errno.h>int main()
{printf("one:hello hua qing\n");fclose(stdout);printf("two :hello hua qing\n");return 0;
}
返回值:

成功:0
失败:EOF

3.fprintf()

头文件:

#include<stdio.h>

使用实例:

int fprintf(FILE *stream, const char *format, …(arg));
将第二个参数的内容写入文件
stream:文件指针
format:同printf
arg:可变参,同printf

#include<stdio.h>
#include<stdlib.h>
int main()
{FILE *fp;fp = fopen("file.txt","w");if(fp==NULL){perror("fopen");}printf("one:hello\n");//往终端打印数据fprintf(stdout,"hi\n");//向stdout中打印数据fprintf(fp,"My age is %d",30);//向stdout中打印数据char buf[20] = {0};
//    strcpy(buf,"hello");puts("------------------------------");sprintf(buf,"file%d",100);printf("%s\n",buf);char buf1[20] = "123456";puts("------------------------------");int num = atoi(buf1);printf("num = %d\n",num);return 0;
}
返回值:

成功:写入字节数;
失败:0

4.fputc()

头文件: #include<stdio.h>
使用实例:

int fputc(int c, FILE *stream);
向文件写入一个字符
c:将要写入的字符;
stream:文件指针;

#include<stdio.h>int main()
{//    fputc('h',stdout);
//    fputc('a',stdout);
//    fputc(97,stdout);FILE *fp;if((fp = fopen("file.txt","w+"))==NULL){perror("fopen");return -1;}//写指针  会往后偏移fputc('h',fp);fputc('e',fp);fputc('l',fp);fputc('l',fp);fputc('o',fp);return 0;
}
返回值:

成功:要写入的字符;
失败:EOF

5.fgetc()

头文件

#include <stdio.h>

使用实例

int fgetc(FILE *stream);
从文件中读取字符。
stream:文件指针

#include<stdio.h>int main()
{//    int  a = fgetc(stdin);
//    printf("a = %d  a = %c\n",a,a);FILE *fp;if((fp=fopen("file.txt","r"))==NULL){perror("fopen");return -1;}
#if 0
int vla;printf("val = %c",val);val = fgetc(fp);printf("val = %c",val1);val = fgetc(fp);printf("val = %c\n",val2);
#endifint val;while((val = fgetc(fp))!=EOF){printf("%c",val);    }return 0;
}
返回值

成功:读取到的字符
失败:EOF

6. fputs()

头文件 #include<stdio.h>
使用实例

int fputs(const char *s, FILE *stream);
参数:
s:要写入的字符串;
stream:文件指针(指向要操作的文件);

#include<stdio.h>int main()
{//自带换行
//    puts("-------------------------");//不会自带换行
//    fputs("hello\n",stdout);int num;FILE *fp;if((fp = fopen("file.txt","w"))==NULL)//存在就会清空{perror("fopen");return -1;}num = fputs("hello world",fp);printf("num = %d\n",num);return 0;
}
返回值

成功:返回一个非负值,默认为1
失败:EOF

7.fgets()

注意:
1)如果第二个参数设置的值 n 小于实际的字节数,只会保存前 n-1 个字节,最后一个位置
补\0
2)如果第二个参数设置的值 n 大于实际的字节数,会把换行符\n 也保存在字符串里面
(如何去除 buf 里面保存的换行符?将\n 变为\0 )
3)fgets 函数读取文件内容时,每次n个字节(取决于第二个参数),遇到行结束符\n 就会立即返回
例:
假设文件第一行有数据“hello world” 11个字节
当fgets第二个参数n设置大于 11 即读取时 会将换行符也读取进去 输出打印时 就会多个换行
此时strlen(buf)是12个字节
当fgets第二个参数n设置小于 11 即读取时 会读取到n-1个字节 留一个字节给尾0

头文件 #include <stdio.h>
使用实例

char *fgets(char *s, int size, FILE *stream);
从文件中读取字符串。
参数:
s:读取的内容
size:一次读取的字节数
stream:文件指针

#include<stdio.h>
#include<string.h>
int main()
{char buf[20];FILE *fp;
//    fgets(buf,10,stdin);
//    printf("buf = %s\n",buf);if((fp = fopen("file.txt","r"))==NULL){perror("fopen");return -1;}fgets(buf,sizeof(buf),fp);printf("buf = %s\n",buf);fgets(buf,sizeof(buf),fp);//解决多一个换行的原因buf[strlen(buf)-1]=  '\0';printf("buf = %s\n",buf); printf("strlen(buf) = %ld\n",strlen(buf));return 0;
}
返回值

成功:若函数获取字符串放入数组中,则返回该数组的首地址指针;读完返回NULL;
失败:NULL

文件IO相关函数

  1. open()
  2. read()
  3. write()
  4. stat()
  5. opendir()/closedir()
  6. readdir()
  7. closedir()

1.stat()

stat() 函数可用于Unix/Linux系统中获取文件或目录的详细信息。它返回一个元组,其中包含有关文件或目录的细节,例如文件大小、修改时间、访问权限等。这些信息可以用于检查文件或目录的完整性,以及在文件系统中进行操作。

头文件

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

使用实例

获取一个文件的信息
pathname:文件名
statbuf:获取的文件的信息结构体
stat结构体包含:

 struct stat {dev_t     st_dev;         /* 设备ID */ino_t     st_ino;         /* inode节点号 */mode_t    st_mode;        /* 文件得类型和模式 */nlink_t   st_nlink;       /* 硬链接个数 */uid_t     st_uid;         /* 当前用户id */gid_t     st_gid;         /* 当前用户组*/dev_t     st_rdev;        /* Device ID (if special file) */off_t     st_size;        /* Total size, in bytes */blksize_t st_blksize;     /* Block size for filesystem I/O */blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */struct timespec st_atim;  /* Time of last access */struct timespec st_mtim;  /* Time of last modification */};The following mask values are defined for the file type:S_IFMT     0170000   bit mask for the file type bit fieldS_IFSOCK   0140000   socket    套接字文件S_IFLNK    0120000   symbolic link     链接文件S_IFREG    0100000   regular file      普通文件S_IFBLK    0060000   block device      块设备文件S_IFDIR    0040000   directory         目录文件S_IFCHR    0020000   character device   字符设备文件S_IFIFO    0010000   FIFO                管道文件总结:高两位是判断文件类型S_ISUID     04000   set-user-ID bitS_ISGID     02000   set-group-ID bit (see below)S_ISVTX     01000   sticky bit (see below)S_IRWXU     00700   当前用户可读可写可执行权限S_IRUSR     00400   当前用户可读权限S_IWUSR     00200   当前用户可写权限S_IXUSR     00100   当前用户可行性权限S_IRWXG     00070   用户组可读可写可执行权限S_IRGRP     00040   用户组可读权限S_IWGRP     00020   用户组可写权限S_IXGRP     00010   用户组可执行权限S_IRWXO     00007   others (not in group) have read,  write,  andexecute permissionS_IROTH     00004   others have read permissionS_IWOTH     00002   others have write permissionS_IXOTH     00001   others have execute permission总结:后三位是文件的权限创建硬链 ln 源文件  目标文件如果加上-s 选项  则创建软链接文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include<stdio.h>int main()
{struct stat mystat;int ret;ret = stat("test",&mystat);if(ret==-1){1        perror("stat");return -1;}
#if 0printf("mystat.st_ino = %ld\n",mystat.st_ino);printf("mystat.st_mode = %#o\n",mystat.st_mode);printf("mystat.st_nlink = %ld\n",mystat.st_nlink);
#endifswitch(mystat.st_mode&S_IFMT){case S_IFSOCK:printf("s");break;case S_IFLNK:printf("l");break;case S_IFREG:printf("-");break;case S_IFBLK:printf("b");break;case S_IFDIR:printf("d");break;case S_IFCHR:printf("c");break;case S_IFIFO:printf("p");break;}for(int n=8;n>=0;n--){if(mystat.st_mode&(1<<n)){switch(n%3){case 1:printf("w");break;case 2: printf("r");break;case 0:printf("x");break;}}else{printf("-");}}printf("\n");return 0;
}
返回值

成功:0
失败:-1

2. open()

头文件

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

使用实例

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
参数:
pathname:文件名,可以添加路径,如果不添加默认是当前目录
flags:标志位
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_APPEND 文件存在则追加
O_TRUNC 文件存在则清空
O_CREAT 如果文件不存在则创建
O_EXCL 与 O_CREAT 一起使用,如果文件存在则报错
mode:指定创建文件的权限,一般使用八进制表示,0664
只有当 flags 有 O_CREAT 权限时才会指定当前参数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>int main()
{int fd;//以只读的方式打开  文件不存在则报错    //fd = open("file.txt",O_RDONLY);//以只读的方式打开  文件则创建 指定第三个参数值fd = open("file.txt",O_RDONLY|O_CREAT,0664);if(fd == -1)//创建失败返回一个错误(perror){perror("open");return -1;}//文件描述符会递增printf("fd = %d\n",fd);fd = open("file.txt",O_RDONLY|O_CREAT,0775);printf("fd = %d\n",fd);fd = open("file.txt",O_RDONLY|O_CREAT,0775);printf("fd = %d\n",fd);return 0;
}

返回值

成功:返回文件描述符
失败:-1

3. read()

头文件

#include <unistd.h>

使用实例

ssize_t read(int fd, void *buf, size_t count);
函数功能:读取文件信息
参数:
fd:文件描述符
buf:存放读到数据
count:读取多少字节

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{int fd;fd = open("file.txt",O_RDONLY|O_CREAT,0775);if(fd == -1){perror("open");return -1;}char buf[32];int ret;ret = read(fd,buf,32);printf("ret = %d  buf=%s\n",ret,buf);memset(buf,0,32);//读到文件尾返回0ret = read(fd,buf,32);printf("ret = %d  buf=%s\n",ret,buf);return 0;
}
返回值

成功:返回读到的字节数
读到文件尾时返回 0
失败:-1

4. write()

头文件

#include <unistd.h>

使用实例

ssize_t write(int fd, const void *buf, size_t count);
功能:向文件写数据
参数:
fd:文件描述符
buf:要写入的内容
count:要写入的字节数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{int fd;fd = open("file.txt",O_WRONLY|O_CREAT|O_TRUNC,0775);if(fd == -1){perror("open");return -1;}char buf[32]  = "hello";write(fd,buf,7);return 0;
}
返回值

成功:返回写到的字节数
失败:-1

5. opendir()/closedir()

头文件

#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:目录流指针,opendir 的返回值

返回值

成功:0
失败:-1

6. readdir()

头文件

#include <dirent.h>

使用实例

struct dirent *readdir(DIR *dirp);
功能:获取目录中文件的信息
参数:
dirp:目录流指针,opendir 的返回值

#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#if 0
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 supportedby all filesystem types */char           d_name[256]; /* Null-terminated filename */
};
#endif
int main()
{DIR *dir;struct dirent*mydirent;if((dir = opendir("test"))==NULL){perror("opendir");return -1;}
#if 0mydirent = readdir(dir);printf("mydirent->d_ino = %ld\n",mydirent->d_ino);printf("mydirent->d_name = %s\n",mydirent->d_name);
//运行一次就读取一个文件信息mydirent = readdir(dir);printf("mydirent->d_ino = %ld\n",mydirent->d_ino);printf("mydirent->d_name = %s\n",mydirent->d_name);
#endifwhile(mydirent = readdir(dir)){printf("d_ino = %ld  d_name = %s\n",mydirent->d_ino,mydirent->d_name);}return 0;
}
返回值

成功:保存文件信息的结构体
失败:NULL
如果目录信息读取完毕,返回 NULL

7. closedir()

头文件

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

使用实例

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

返回值

成功:0
失败:-1

linux环境下IO的常用函数相关推荐

  1. Linux环境下几种常用的文件系统

    Linux环境下几种常用的文件系统: 1.ext2 ext2是为解决ext文件系统的缺陷而设计的可扩展的.高性能的文件系统,又被称为二级扩展文件系统.它是Linux文件系统中使用最多的类型,并且在速度 ...

  2. linux四种文件系统,Linux环境下常用的四种文件系统

    Linux环境下几种常用的文件系统 1.ext2 ext2是为解决ext文件系统的缺陷而设计的可扩展的.高性能的文件系统,又被称为二级扩展文件系统.它是Linux文件系统中使用最多的类型,并且在速度和 ...

  3. Linux系统常用函数,浅谈linux下的一些常用函数的总结(必看篇)

    1.exit()函数 exit(int n)  其实就是直接退出程序, 因为默认的标准程序入口为int main(int argc, char** argv),返回值是int型的. 一般在shell下 ...

  4. linux函数删除某文件,Linux环境下用C++删除指定文件

    Linux环境下用C++删除指定文件 "Talk is cheap, show me the code!" #include #include #include #include ...

  5. linux环境下常用的网络命令ping、telnet、traceroute、tcpdump

    文章目录 前言 网络 网络命令 ping telnet nc traceroute tcpdump 总结 前言 因特网(Internet)的前身是美国国防部高级研究计划局(ARPA)用于军事目的的通信 ...

  6. linux环境下如何部署war包及常用命令

    linux环境下部署war包需要用到的一些命令 linux环境下部署war包 测试工具 常用的一些命令 对于使用navicat或者workbench进行脚本测试的一些注意事项执行 linux环境下部署 ...

  7. mosquitto在Linux环境下的部署/安装/使用/测试

    看了有三四天的的源码,(当然没怎么好好看了),突然发现对mosquitto的源码有了一点点感觉,于是在第五天决定在Linux环境下部署mosquitto. 使用传统源码安装步骤: 步骤1:http:/ ...

  8. Linux环境下的网络编程

    本文介绍了在Linux环境下的socket编程常用函数用法及socket编程的一般规则和客户/服务器模型的编程应注意的事项和常遇问题的解决方法,并举了具体代  码实例.要理解本文所谈的技术问题需要读者 ...

  9. osg linux 环境配置,Linux环境下jdk1.8的下载与安装

    Linux环境下jdk1.8的下载与安装 1.下载 Oracle官网下载相应的版本,官网地址:https://www.oracle.com/java/technologies/javase/javas ...

最新文章

  1. iOS开发使用Unwind Segue进行返回
  2. css字体居中_简单介绍CSS.
  3. SQLCLR(五)聚合
  4. 如何提高lstm的预测精度_如何提高示波器的测试精度?五大因素助您了解!
  5. Java扑克牌(洗牌Collections.shuffle)
  6. 工业定焦镜头的选型公式
  7. 在EORow或者VORow中对数据进行重复性校验
  8. mysql分表全局查询_mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表...
  9. 死磕 18 个 Java 8 的日期处理,工作必用!
  10. 如何在横竖屏切换时Activity内容不变
  11. VirtualBox安装黑苹果
  12. 我不曾忘记的初心-屌丝逆袭
  13. 336亿的生意——你所不了解的Dapp这一年(下)
  14. c语言命令笔记本电脑快捷键,实用的电脑操作技巧(附快捷键)
  15. openwrt路由器挂载sdcard为overlay
  16. response setHeader 设置下载中文文件名乱码问题
  17. 数学基础:和式极限(可爱因子理解) 连续,极限定义: 导数: 微积分: 推荐数学电影
  18. 机器学习对我们生活的改变
  19. ipa反编译修改icon,简洁教程
  20. window.event.keyCode - 兼容chrom和Firefox

热门文章

  1. 使用jasypt 进行数据库配置加密
  2. 锐化 清晰度 对比度的区别
  3. C10k-problem
  4. linux下查看gaussian结构,察看Gaussian全部IOp的方法
  5. 来,看一个真实的用户分析案例!
  6. 用Python告诉你广州房租现状
  7. HTMLCSSHTTP
  8. JS对全角与半角的验证,相互转化以及介绍 | CSDN创作打卡
  9. java初始化三门课程_[Java] 实验4参考代码
  10. PyCharm关闭更新提示