Linux文件I/O有两种实现方式:系统调用和标准函数库调用。而两种方式所操作的对象分别是文件描述符(如:STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO)和I/O流(如:stdin,stdout,stderr),这是我一个经常混淆的地方。
- 在执行系统调用时,Linux必须从用户代码切换到内核代码执行,然后返回用户代码,系统将会在此过程中产生很多额外开销,从而影响系统性能(为缓解此问题,可以减少系统调用的次数,并且让每次系统调用完成尽可能多的工作)
- 部分硬件会限制底层系统调用一次所能读写的数据块大小。
- 全缓冲:在填满缓冲区后才进行一次实际I/O操作。当然也可以调用fflush冲洗一个流。当输入输出不涉及交互式设备时,通常采用的是全缓冲,例如磁盘上的文件。
- 行缓冲:当在输入输出中遇到换行符时,标准I/O执行一次I/O操作。eg.printf.
- 不带缓冲:标准出错流stderr是不带缓冲的,这就使得错误信息很快被显示出来。
//标准I/O库实现,read.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char ch;
/*以只读、文本的形式打开本路径下一个名为hello的文件*/
if((fp=fopen("hello","rt"))==NULL)
exit(EXIT_FAILURE);
ch=fgetc(fp);
while(ch!=EOF) //文件尾
{
putchar(ch);
ch=fgetc(fp); //读取一个字符
}
fclose(fp);
exit(EXIT_SUCCESS);
}
//-----------------------------------------------------------------------------------------------------------------
//系统调用,read.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFER_SIZE 100
int main(int argc,char **argv)
{
int i,fd,lenght;
char buffer[BUFFER_SIZE];
if(argc<2)
{
printf("You haven't input the file name!\n");
exit(EXIT_FAILURE);
}
for(i=1;i<argc;i++)
{
if(access(argv[i],F_OK)==-1) //检查文件是否存在
{
printf("%s:there is no such file\n",argv[i]);
continue;
}
/*以读写的方式打开*/
if((fd=open(argv[i],O_RDWR|O_CREAT,0775))>=0)
{
/*read(...)的返回值是读取到内容的字节数*/
while(read(fd,buffer,sizeof(buffer)))
printf("%s\n",buffer);
close(fd);
}
else
perror(NULL);
}
exit(EXIT_SUCCESS);
}
//---------------------------------------------------------------------------------
//系统调用,write.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char **argv)
{
int fd;
int filestateflag;
if(argc!=3)
{
printf("Command is incorrect!\n");
exit(EXIT_FAILURE);
}
/*if((fd=open(argv[1],O_CREAT|O_RDWR,0775))>=0)
{
lseek(fd,0,SEEK_END);
write(fd,argv[2],strlen(argv[2]));
}*/
if((fd=open(argv[1],O_APPEND|O_CREAT|O_RDWR,0775))>=0)
{
filestateflag = fcntl (fd,F_GETFL,0);
printf("文件描述状态标志是:%d\n",filestateflag);
write(fd,argv[2],strlen(argv[2]));
}
else
{
perror(NULL);
exit(EXIT_FAILURE);
}
close(fd);
exit(EXIT_SUCCESS);
}