一、文件的概念
①文件按类型的分类
1)常规文件:ASCII码文件,二进制文件(以'-'开头)
2)目录(以'd'开头,directory)
3)字符设备,是设备文件的一种(键盘鼠标之类的,以'c'开头,character)
4)块设备,是设备文件的一种(硬盘一类的,以'b'开头,block)
5)符号链接(以'l'开头)
6)有名管道(以'p'开头,pipe)
7)套接口
二、缓冲的三种类型
①全缓存:填满I/O缓存才会进行实际的I/O操作。可以通过强制刷新(fflush)进行刷新
②行缓存:输入输出时遇到'\n'的时候进行I/O操作,一下将通过一个程序说明行缓冲现象(printf):
#include<stdio.h>
#include <unistd.h>
#define NUM 1024
int main()
{
char a[4096];
int i=0,count=0;
for(;i<=NUM;i++)
a[i]='w';
printf("%s",a);
sleep(4);
printf("\n");
return 0;
}
程序的结果:改变宏定义NUM的值,会发现当值小于1024时输出时会在4s之后再输出,当NUM的值大于1024的时候则会立即输出。
说明了行缓冲区的大小为1024k。
③不带缓存
比如stderr就不带缓存:
#include <stdio.h>
int main()
{
fprintf(stderr,"hello stderr");
while(1);
return 0;
}
运行结果会输出"hello stderr":
然而:
#include <stdio.h>
int main()
{
fprintf(stdout,"hello stdout");
while(1);
return 0;
}
运行结果并不会输出"hello stdout":
三、标准I/O
①fopen与fclose
②freopen
运行不会有结果输出,因为freopen关闭了stdout。
但是使用cat 查看openfile.c的时候:
③读写流
fgetc与fputc
fgetc从流中读取下一个字符,返回整型。读取至末尾或者文件错误时是返回EOF。
fputc:向流中写一个字符。错误时返回EOF。
结果:
fgets与fputs
fgets:从文件指针stream中读取size-1个字符,存到以s为起始地址的空间里,直到读完一行或者遇到EOF,如果成功则返回s的指针,否则返回NULL。
向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回为一个非负整数;否则返回EOF(符号常量,其值为-1)。
程序实现了文件的复制
fread与fwrite
通过以下例子进行理解:
运行之后输出hello
fseek、ftell与rewind
如果执行成功,stream将指向以whence为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值(超出文件末尾位置,还是返回0。往回偏移超出首位置,返回-1,且指向一个-1的位置)。
whence:SEEK_SET :以文件开头为基准位置
SEEK_CUR:以当前位置为基准
SEEK_END:以文件结尾为基准
offset:向前为正,退回为负
下面将以一个例子进行说明:
SEEK_SET:
结果为
SEEK_CUR:
结果为:
SEEK_END:
结果为:
ftell
ftell:显示当前位置
结果为:
rewind = fseek(fp,0,SEEK_SET)等效
四、文件I/O
①头文件:
②open 与 close:
方式与fopen是类似的。Open函数存在标志(常用):
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_EXCL:创建一个唯一的文件,具有排他性
O_CREAT:创建以个文件
③read 与write
可看出read需要办函头文件unistd.h,回值为有符号整数。fd是文件描述符。执行成功后返回读到的数量,失败时返回-1;
可看出write与read是类似的。举个例子:
结果为:
④lseek
与fseek是差不多的。参照fseek即可。