Linux学习之应用开发阶段(文件IO与标准IO)

言之者无罪,闻之者足以戒。 ——《诗序》
Linux的高级编程感知内核的强大存在以及内核的强大功能.
1、文件管理
2、进程管理
3、设备管理
4、内存管理
5、网络管理
应用---->内核---->硬件
系统编程之IO:
文件IO
标准IO
目标IO
文件IO:
用到的四个函数:
open
read
write
close
1、open-打开或创建一个文件
open(char *,flag.mode)在fcntl.h文件中声明。函数的作用:创建或打开某个文件,参数:最多有三个参数;
第一个参数:char * 包含有文件名和路径
第二个参数:flag 打开文件的方式
第三个参数:mode 创建文件的权限
1)flag具体参数意义:

flag 功能
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 创建一个文件
O_EXCT 如果使用O_CREAT时文件存在,则可返回错误消息,这一参数可测试文件是否存在
O_TRUNC 打开文件(会把已经存在的内容删除)
O_APPEND 追加方式打开(不会把已经存在的内容删除)

2)返回值
成功:文件描述,它是一个非负的正整数,即文件的ID号,相当于人的身份证号;
出错:-1;
在程序的最后要有close(文件名)函数
open函数创建文件时的权限等于mode&(~umask);
umask称为掩码:就是将某些位掩掉的意思;
umask 0000:这条命令的作用是设置掩码的值为0000,就是不掩任何一位
ls -lai 可以查看文件的inode号;
2、write(int fd,void *buf,size_t count)
第一个参数:向哪一个文件中写;第二个参数:向这个文件中写什么内容;第三个参数:向这个文件中写多少 。函数的返回值:是实际写的字节数
3、read(int fd,void *buf,size_t count)
第一个参数:从哪一个文件中读;第二个参数:读到什么地方去;第三个参数:读多少个 。函数的返回值:是实际读的字节数
4、lseek(int fd,off_t offset,int whence)
该函数的头文件:systypes.h unistd.h
功能:调整读写的位置指针;
第一个参数:要调整的文件的文件描述符;
第二个参数:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移);
第三个参数:当前位置的基点,有三个标志
SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。
函数的返回值:成功:文件当前的位置,出错:-1;
标准IO
标准IO与文件IO的区别?
文件IO:是直接调用内核提供的系统调用 函数,头文件是unistd.h
标准IO:是间接的调用系统函数,头文件是stdio.h
之前学过的输入输出相关的函数就是标准的输入(键盘),标准的输出(显示器)
标准IO中的相关函数,不仅可以读写普通文件,也可以向标准的输入或标准的输出中读或写;
三个缓存的概念(数组):
1、我们的程序中的缓存,就是你想从内核读写的缓存(数组)—用户空间的缓存
2、每打开一个文件,内核在内核空间也会开辟一块缓存,这个叫内核空间的缓存;
文件IO中的写即是将用户空间中的缓存写到内核空间的缓存中;
文件IO中的读即是将内核空间的缓存写到用户空间中的缓存中;
3、标准IO的库函数中也有一个缓存,这个缓存称为-----库缓存
就比如我们在程序中调用printf()输出函数,就要满足库缓存的要求才会实现真正的调用
1)在要显示的内容中遇到‘\n’是,即会将库缓存的内容写到内核中,即调用了系统调用函数
2)库缓存写满时,会调用系统调用函数
下面粘贴一下代码以示说明:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
        char buf[]="hello Linux\n";
        printf("%s",buf);       
        while(1);
        return 0;

}

大家可以试一下,如果在buf[]="hello Linux\n"中把‘\n’去掉还是否能显示这个字符串,答案是不能,这就我们上面说的第一个条件;
下面再写一段代码来说明第二个条件:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
        char buf[]="hello Linux";
        int i=1;
        while(i<=93)
        {
                printf("%s",buf);       
                i++;
        }
        printf("lm");   
        while(1);
//      printf("%d",sizeof(buf));
        return 0;

}  

我们从这段代码中就可以看出库缓存的大小:11*93+1=1024;
可能会有人问为什么你最后的输出语句明明是写的两个字符,为什么你只加了1,那是因为加一是刚好写满,加二就溢出就会显示在屏幕上了;
我总觉得上面代码的颜色太单调所以我也给大家截一张图颜色比较多一点,看着说不定心情会好很多:
在这里插入图片描述
文件IO与标准IO:
在这里插入图片描述

1、FILE*fopen(const char *path,const char *mode)
返回值:FILE *文件流指针 类似于文件IO中的文件描述符
FILE定义:struct _IO_FILE, 在/usr/include/libio.h
包含读写缓存的首地址、大小、位置指针等
标准的输入流:stdin 0
标准的输出流:stdout 1
标准的出错流:stderr 2
mode:

r或rb 打开只读文件,该文件必须存在
r+或r+b 打开可读写的文件,该文件必须存在
w或wb 打开只写文件,若文件存在则文件长度清为0,即会擦除文件以前内容。若不存在则建立该文件
w+或w+b或wb+ 打开可读写文件,若文件存在则文件长度清为0,即会擦除文件以前的内容,若文件不存在则建立该文件
a或ab 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留
a+或a+b或ab+ 以附加的方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留

mode :
1)、b:二进制文件
2)、r:只读方式打开文件,文件必须存在
3)、w或a:只写方式打开文件,文件不存在则建立;
二者之间的区别:w等价于O_TRUNC ,a等价于O_APPEND
4)、+:读写方式打开文件,文件必须存在;
例:以读写方式打开一个文件,该文件必须存在: r+
以追加方式打开一个文件,若文件不存在,则创建:a或a+
在打开一个文件的最后要有关闭函数:fclose();
修改文件权限的方法:
fopen函数创建文件时的权限等于mode&(~umask);
umask称为掩码:就是将某些位掩掉的意思;
umask 0000:这条命令的作用是设置掩码的值为0000,就是不掩任何一位

猜你喜欢

转载自blog.csdn.net/weixin_42994525/article/details/82978879