IO文件
操作系统为了方便用户使用系统功能而对外提供的一组系统函数。称之为 系统调用 其中有个 文件IO
一般都是对设备文件操作,当然也可以对普通文件进行操作。
它是一个基于Linux内核的没有缓存的IO机制
特性:
.1 没有缓存区
.2 操作对象不在是流,而是文件描述符
.3文件描述符
很小的非负的整数 int 0-1023
内核每打开一个文件就会获得一个文件 描述符
每个程序在启动的时候操作系统默认为其打开
三个描述符与流对象匹配:
0 ==>STDIN_FILENO === stdin
1 ==>STDOUT_FILENO == stdout
2 ==>STDERR_FILENO == stderr
后面创建的文件都从3开始
标准IO和文件IO的后缀
w == O_WRONLY | O_CREAT | O_TRUNC
w+ == O_RDWR | O_CREAT | O_TRUNC
r == O_RDONLY
r+ == O_RDWR
a == O_WRONLY | O_CREAT | O_APPEND
a+ == O_RDWR|O_CREAT|O_APPEND
3.文件IO的操作流程
(1)打开:open
(2)读写:read / write
(3)关闭:close
缓冲区
缓冲区
缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。
为什么要引入缓冲区
比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。现在您基本明白了吧,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。
行缓冲,1k, terminal,主要用于人机交互stdout
缓存区满或者遇到\n刷新 1024
行缓存多是关于终端的一些操作
1.遇到\n刷新
2.缓存区满刷新
3.程序结束刷新
4.fflush刷新 fflush(stdout);
全缓冲,4k,主要用于文件的读写
缓存区满刷新缓存区 4096
对普通文件进行标准IO操作,建立
的缓存一般为全缓存
刷新条件:
1.缓存区满刷新
2.程序结束刷新
3.fflush来刷新 fflush(fp);
无缓冲,0k 主要用于出错处理信息的输出 stderr
不对数据缓存直接刷新
printf();==>>stdout
fprintf(strerr,"fopen error %s",filename);
界面交互 出错处理
使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。
缓冲区的大小是可以设置
open函数
int main(int argc, char *argv[])
{
int fd= open("1.txt",O_WRONLY | O_CREAT|O_TRUNC,0666);
if(-1 == fd)
{
printf("open error\n");
return 1;
}
printf("fd is %d\n",fd);
return 0;
}
open("1.c",O_WRONLY|O_CREAT,0666 );
int open(const char *pathname, int flags,int mode);
功能:
获得一个文件描述符
参数:
pathname:文件名
flags:
O_RDONLY |
O_WRONLY
O_RDWR
O_CREAT, 创建文件
O_EXCL,需要和O_CREAT同时使用,表示新建的文件不能存在,成功,否则open就会失败
O_NOCTTY,不是终端设备
O_TRUNC文件内容清空
O_APPEND追加
O_ASYNC异步io,什么时候io不确定,
O_NONBLOCK非阻塞
返回值:
成功返回文件描述符
失败返回-1
write函数
int main(int argc, char *argv[])
{
int fd= open("1.txt",O_WRONLY | O_CREAT|O_TRUNC,0666);
if(-1 == fd)
{
printf("open error\n");
return 1;
}
printf("fd is %d\n",fd);
char buf[128]="hello,world";
int wr_ret = write(fd,buf,strlen(buf));
if(-1 == wr_ret)
{
printf("write error\n");
return 1;
}
close(fd);
return 0;
}
char buf[1024];
ssize_t write(int fd, const void *buf, size_t count);
功能:
通过文件描述符向文件中写一串数据
参数:
fd:文件描述符
buf:要写入文件的字符串的首地址
count:要写入字符的个数
返回值:
成功返回实际写入的个数
失败返回-1
read 函数
int main(int argc, char *argv[])
{
int fd= open("1.txt",O_RDONLY);
if(-1 == fd)
{
printf("open error\n");
return 1;
}
printf("fd is %d\n",fd);
char buf[512]={0};
int rd_ret = read(fd,buf,sizeof(buf));
if(rd_ret<=0)
{
printf("read eof or error\n");
return 1;
}
printf("ret %d,%s\n",rd_ret,buf);
close(fd);
return 0;
}
ssize_t read(int fd, void *buf, size_t count);
功能:
通过文件描述符读取文件中的数据
参数:
fd:文件描述符
buf:存放数据空间的首地址
count:要读到数据的个数
返回值:
成功返回读到数据的个数
失败返回-1
读到文件结尾返回0
seek函数
int main(int argc, char *argv[])
{
int fd= open("1.txt",O_WRONLY);
if(-1 == fd)
{
printf("open error\n");
return 1;
}
printf("fd is %d\n",fd);
off_t offset = lseek(fd,6, SEEK_SET);
printf("offset %ld\n",offset);
write(fd,"china",5);
close(fd);
return 0;
}
lseek fseek, rewind ftell
off_t lseek(int fd, off_t offset, int whence);
功能:
定位光标的位置
参数:
fd:文件描述符
offset:偏移量
正:向后偏移
负:向前偏移
零:不偏移
whence:
SEEK_SET
SEEK_CUR
SEEK_END
返回值:
成功返回偏移量
失败返回-1
1、不支持O_APPEND的追加模式,无法生成空洞文件。
2、lseek函数执行失败,文件指针还在偏移前的位置。
3、lseek函数在设备文件上偏移无效。
阻塞:程序因为某种条件没有被触发,而导致'0' '\0'