说明:本次试验阶段所使用的Ubuntu版本为16.04。本人写博客是为了记录自己所学的知识,以便日后复习使用。
标准IO是什么(标准IO概念)
标准IO是标准C库中定义的一系列关于IO操作的函数,标准IO是高级IO操作,其声明包含在stdio.h的头文件中
文件IO是什么(文件IO概念)
文件IO是封装了一系列对文件进行操作的API函数,是低级IO操作,属于系统直接调用
什么时候使用标准IO什么时候使用文件IO(标准IO与文件IO的区别)
1.标准IO操作文件的入口是文件流,适用于文本文件的读写;文件IO操作文件的入口是文件描述符,适用于二进制文件以及底层设备的访问
2.标准IO可操作缓冲区,文件IO不能
标准IO相关API
打开/关闭文件
打开---fopen
头文件:#include <stdio.h>
函数原型:FILE* fopen(const char* path,const char* mode);
参数:path---文件路径及其名称
mode---打开文件的方式:
r:只读---流位于文件开始的位置
r+:读写---流位于文件开始的位置
w:覆盖写---流位于文件开始的位置
w+:读写(覆盖写)---文件不存在则被创建--流位于文件开始的位置
a(英文全称append):文件末尾追加写,不覆盖原本文件内容---文件不存在则被创建--流位于文件末尾
a+:读写---文件不存在则被创建--读(流初始位于文件开始)/写(在末尾追加写)
返回值:成功则返回该文件指针,失败则返回NULL
关闭---fclose
头文件:#include <stdio.h>
函数原型:int fclose(FILE* stream);
参数:stream---文件指针
返回值:成功返回0,失败返回-1
对文件进行读写操作
读操作
getc
头文件:#include <stdio.h>
函数原型:int getc(FILE* stream);
函数功能:从指定的文件中读取单个字符
参数:stream--文件指针
返回值:成功返回所读取字符的ASCII码,失败返回-1
fgetc
头文件:#include <stdio.h>
函数原型:int fgetc(FILE* stream);
函数功能:与getc功能相同
参数:stream--文件指针
返回值:成功返回所读取字符的ASCII码,失败返回-1
getchar
头文件:#include <stdio.h>
函数原型:int getchar(void);
函数功能:从标准输入流中获取单个字符---相当于getc(stdin);
参数:无
返回值:成功返回该字符的ASCII码,失败返回-1
补充:
stdin---标准输入流--通常对应终端键盘
stdout---标准输出流--对应终端屏幕
stderr---标准错误流--对应终端屏幕
gets
头文件:#include <stdio.h>
函数原型:char* gets(char *s);
函数功能:在行缓冲区刷新之前从终端读取一串字符并将获取的字符串放入s的首地址的存储单元中
参数:s---目标字符存放的首地址
返回值:成功返回char *类型的地址,失败返回NULL
通常不使用该函数,因无法确定读出的字符的长度,该函数会带来些许未知的字符
fgets
头文件:#include <stdio.h>
函数原型:char* fgets(char *s,int size,FILE* stream);
函数功能:从文件流中读取size字节的字符,并将其存放在s的首地址中
参数:s---存放所读取的字符串的首地址
size---读取的字节数的大小
stream---文件流
返回值:成功返回s的首地址,失败返回NULL
fread
头文件:#include <stdio.h>
函数原型:size_t fread(void *ptr,size_t size,size_t nmemb,FILE* stream);
size_t ---typedef unsigned int size_t
函数功能:从文件流中读取nmemb次,每次读取size个字节,并将读取的字符内容存放在ptr中
参数:ptr---存放读取字符串的首地址
size---字节数
nmemb---读取次数
stream---文件流
返回值:成功返回实际读取的字符数,失败则返回0
写操作
putc
头文件:#include <stdio.h>
函数原型:int putc(int c,FILE * stream);
函数功能:向文件流中写入单个字符
参数:c---向文件中写入的单个字符的ASCII码
stream---文件流
返回值:成功返回写入的字符的ASCII码,失败返回-1
fputc
头文件:#include <stdio.h>
函数原型:int fputc(int c ,FILE* stream);
函数功能:向文件流中写入单个字符
参数:c--写入的单个字符的ASCII码值
stream--文件流
返回值:成功返回写入字符的ASCII码,失败-1
putchar
头文件:#include <stdio.h>
函数原型:int putchar(int c);
函数功能:等同于putc(c,stdout);---即向标准输出流中写入一个字符
参数:c---输入的字符
返回值:成功返回该字符的ASCII码,失败则返回-1
puts
头文件:#include <stdio.h>
函数原型:int puts(const char* s);
函数功能:向标准输出流中写入字符串s,且会自动追加一个换行符
参数:s---要写入的字符串
返回值:成功返回非负数,失败返回-1
fputs
头文件:#include <stdio.h>
函数原型:int fputs(const char *s,FILE *stream);
函数功能:向文件流中写入字符串,不包含‘\0’
参数:s---要写入的字符串
stream---文件流
返回值:成功返回非负数,失败返回-1
fwrite
头文件:#include <stdio.h>
函数原型:size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream);
函数功能:向文件流中的ptr(首地址)写入nmemb次数据,每次写入size个字符
参数:ptr--目标地址
size--字符数/次
nmemb--写入总次数
stream--文件流
返回值:成功返回写入的项数,失败返回-1
标准IO部分API使用示例
#include <stdio.h>
#include <time.h>
/*向文件中写入字符当前日期*/
int main()
{
FILE *fp;
if(NULL == (fp = fopen("test.txt","w+")))//以写的方式打开文件,文件不存在则创建
{
perror("fopen");
}
//获取系统时间
time_t t;
struct tm *p;
char temp[128] = {0};
time(&t);
p = localtime(&t);
//将系统时间封装成为字符串
sprintf(temp,"%d-%d-%d %2d:%2d:%2d",1900+p->tm_year,1+p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
//文件成功打开写入当前日期
fputs(temp,fp);
fclose(fp);
return 0;
}
文件IO相关API
打开/关闭文件
打开--open
头文件:#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型:int open(const char *pathname,int flags);
函数功能:打开文件
参数:pathname--文件路径
flags--必须包含O_RDONLY,O_WRONLY,O_RDWR中的一个
O_APPEND:
文件以追加模式打开。在每次写入之前,文件偏移量位于文件的末尾,就像使用lseek一样。如果多个进程同时向一个文件追加数据,o_APPEND可能会导致NFS文件系统项上的文件损坏。这是因为NFS不支持追加文件,因此客户机内核必须模拟它,而没有竞争条件是无法做到这一点的。
O_ASYNC:
启用信号驱动I/0:当该文件描述符上的输入或输出成为可能时,生成信号(默认为sIGIO,但可以通过fcntl更改)。此特性仅对终端、伪终端、套接字以及(从Linux 2.6起)管道和fifo可用。
O_CREAT:
如果该文件不存在,则将创建它。将文件的所有者(用户ID)设置为进程的有效用户ID。组所有权(组ID)要么设置为进程的有效组ID,要么设置为父目录的组ID(取决于文件系统类型和挂载选项,以及父目录的模式;请参阅mount中描述的挂载选项bsdgroups和sysvgroups。Mode指定在创建新文件时使用的模式。当在flags中指定o_create或o_TMPFILE时,必须提供此参数;如果没有指定o_create和o_TMPFILE,则mode被忽略。有效模式由进程的umask以通常的方式修改:在没有默认ACL的情况下,创建的文件的模式为(mode & ~umask)。注意,此模式仅适用于对新创建的文件的未来访问;创建只读文件的open()调用很可能返回一个读/写文件描述符。
O_EXCL:
确保这个调用创建了文件:如果这个标志与o_CREAT一起使用,并且pathname已经存在,那么open()将失败。当指定这两个标志时,不遵循符号链接:如果pathname是符号链接,则open()失败,不管符号链接指向哪里。通常,如果不使用O_create,则o_EXCL的行为是未定义的。有一个例外:在Linux 2.6和更高版本上,如果pathname引用块设备,o_EXCL可以不使用o_create。如果块设备正在被系统使用(例如,mounted), open()失败并返回错误EBUSY。
返回值:成功返回文件描述符,失败返回-1
关闭--close
头文件:#include <unistd.h>
函数原型:int close(int fd);
函数功能:关闭一个文件描述符
参数:fd--文件描述符
返回值:成功返回0 失败返回-1
读写操作
读操作
read
头文件:#include <unistd.h>
函数原型:ssize_t read(int fd,void *buf,size_t count);
函数功能:从文件描述符fd中读取count字节的数据存放到buf中
参数:fd---文件描述符
buf---存放count字节的数据地址
count---读取的字节数
返回值:成功返回读取的字节数,失败返回-1
写操作
write
头文件:#include <unistd.h>
函数原型:ssize_t write(int fd,void *buf,count);
函数功能:向文件描述符中写入buf中的count字节的数据
参数:fd--文件描述符
buf---存放数据的首地址
count---字节数
返回值:成功返回写入的字节数,失败返回-1
文件IO部分API使用示例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd;
if(-1 == (fd = open("test.txt",O_RDONLY)))
{
perror("open");
return -1;
}
close(fd);
return 0;
}