标准IO和文件IO的区别
标准IO
- 符合ANSI C标准。
- 带有缓冲区,减少系统调用,提高系统效率。
- 通过流(FILE结构体)来表示一个打开的文件。
- 只能访问普通文件和终端文件。
文件IO
- 符合POSIX(可移植操作系统接口)标准。
- 不具有缓冲机制。
- 采用文件描述符fd来表示一个打开的文件。
- 可以访问各种类型文件
标准IO是基于文件IO实现的。在文件IO增加了缓冲机制。
文件描述符
文件描述符是一个非负数。Linux系统为每个打开的文件分配文件描述符。在一个程序中,从0开始依此递增。文件IO操作通过文件描述符完成。
由于 标准IO是基于文件IO实现的。所以在标准IO中的标准输入/输出/错误流对应了文件IO中的文件描述符。
标准输入stdin,标准输出stdout,标准错误stderr,对应的文件描述符为 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);
flags | 意义 |
---|
pathname | 文件路径 |
O_RDONLY | 只读方式打开 |
O_WRONLY | 可写方式打开 |
O_RDWR | 读写方式打开 |
O_CREAT | 文件不存在则创建文件,用flags指定存取文件 |
O_EXCL | 用O_CREAT创建文件时返回错误信息以测试文件是否存在 |
O_NOCTTY | 文件为终端时,不能为调用open()系统调用的那个进程 |
O_TRUNC | 若文件存在则删除文件中原有数据 |
O_APPEND | 以添加数据在原文件末尾的方式打开 |
测试代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
int fd;
char *test1="/bin/test1";
char *test2="/bin/test2";
if(fd=open(test1,O_RDWR,0777)<0)
{
printf("open %s faild!\n ",test1);
}
printf("%s fd is %d ",test1,fd);
if(fd=open(test2,O_RDWR|O_CREAT,0777)<0)
{
printf("open %s faild!\n ",test2);
}
printf("%s fd is %d ",test2,fd);
}
close
头文件和函数接口
#include <unistd.h>
int close(int fd);
- fd为要关闭的文件描述符。
- 关闭成功时返回0,出错时返回EOF.。
- 程序在结束时会自动关闭所有打开的文件。
- 文件被关闭后,再对文件进行任何操作都是无意义的。
read
头文件和函数接口
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数 | 意义 |
---|
fd | 即将读取文件的文件描述符 |
buf | 存储读入数据的缓冲区 |
count | 将要读入的数据的个数 |
ssize_t | 成功时返回读取的字节数,出错时返回EOF,读到文件末返回0 |
write
头文件和函数接口
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数 | 意义 |
---|
fd | 即将读取文件的文件描述符 |
buf | 要写入的数据缓冲区 |
count | 写入数据的个数,大小不应该大于buf大小 |
ssize_t | 成功时返回写入的字节数,出错时返回EOF,读到文件末返回0 |
测试举例
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define MAX_SIZE 1000
int main()
{
int fd;
char *testwrite = "/bin/testwrite";
ssize_t length_w,ret,length_r=MAX_SIZE;
char buffer_write[] = "Hello Write Function!\n ";
char buffer_read[MAX_SIZE];
if((fd = open(testwrite, O_RDWR|O_CREAT,0777))<0){
printf("open %s failed\n",testwrite);
}
length_w = write(fd,buffer_write,strlen(buffer_write));
if(length_w == -1)
{
perror("write");
}
else{
printf("Write Function OK!\n");
}
close(fd);
if((fd=open(testwrite,O_RDWR|O_CREAT,0777))<0){
printf("open %s faild!\n ",testwrite);
}
if((ret=read(fd,buffer_read,length_r))<0)
{
perror("read");
}
printf("file content is %s \n",buffer_read);
close(fd);
}
lseek
头文件和函数接口
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数 | 意义 |
---|
fd | 文件描述符 |
offset | 偏移量,可正可负 |
whence | 指定一个基准点,基准点+偏移量等于当前位置 |
off_t | 成功时返回0,出错时返回EOF |
whence参数可以为:SEEK_SET(文件开头),SEEK_CUR(当前输入输出位置),SEEK_END(文件末尾).