应用层: 只负责写代码,调用内核层
内核层 : 接到应用层发来的通知,去操作硬件(驱动)
物理层:根据内核层的需求去操作硬件
嵌入式:软件控制硬件,嵌入式对内存进行操作,和内核进行操作来完成操作硬件。
IO:学习API函数接口
linux下一切皆文件
linux是一个多任务的操作系统--------》多进程
IO是在应用层和内核层之间交互。
linux操作系统将文件分为2类:
文本文件: --------------------》.sh,c,c++ 按照程序员的逻辑
二进制文件: --------------------》a.out 按计算机的逻辑去存储
input和output
对内存的输入和输出
内存往外存为输出,外村往内存为输入
内存的特点:
本身速度快,数据掉电就丢失,特点贵
外存:
本身速度慢,数据永久保存,掉电不丢失,便宜
对文件的操作: 打开文件-----------读写文件------------关闭文件
IO分类:
文件IO:由操作系统提供的API接口,也被称为系统调用
每个操作系统的API接口都不一样,
也就造成linux下可执行文件移植到其他平台不能直接使用,因为接口不一致
标准IO: stdio.h,也成为标准C库函数,ANSI C库提供的API接口,标准IO是在文件IO的基础上封装出来的
open read write close lseek
注意:此为linxu下的接口
_open _write _close _read
此为windos操作接口
Open Read Write Close
ios函数接口
man是在线函数查找手册
man 3 库调用 程序库中的函数
man 2 系统调用,内核提供的函数
errno是一个全局变量,保存在#include
中,用于标注错误信息, 当函数报错返回时,会将这个全局变量根据错误信息表中的对应的号码设置一下
全局变量危险哦
文件描述符:是一个文件标志,为数组的下标,是一个int类型的数据,值一般很小
动态分配,一般从3开始

./a.out 刚运行,内核会自动打开三个设备文件,返回三个文件描述符。
标准输入 -------------0 stdin
标准输出 --------------1 stdout
标准错误输出 ---------------2 stderr
头文件:
#include
基本系统数据类型的头文件 #include
是unix/linux系统定义文件状态所在的伪标准头文件 #include
fcntl.h定义了很多宏和open,fcntl函数原型 原型:
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
mode_t 实际上也就是一种无符号整数。
功能:
打开一个文件
参数:
pathname:路径及名称,字符串形式
flag:打开文件的方式:
必须包括:(三选一)
O_RDONLY:只读权限打开文件 必须存在
O_WRONLY:只写权限打开文件
O_RDWR:读写权限打开文件
附加参数(以或的形式去附加)
O_APPEND:以追加写的方式打开文件
O_CREAT:如果文件存在则打开文件,如果文件不存在,则创建文件,如果使用了 O_CREAT这个参数,则需要使用open的第三个参数给与权限, 给与权限是一个8进制的整形,以0开头 ,例如:O_CREAT,0664
O_EXCL:如果文件存在则报错返回
O_TRUNC:以清空的方式打开文件
O_NONBLOCK:以非阻塞方式打开一个文件
返回值:
成功:返回一个文件描述符
失败:返回-1
注意:
使用0666创建文件为什么出来的是0664呢? 是由于操作系统有一个叫做文件掩码的机制,将其它用户权限的可写权限抹掉
使用 umask查看文件掩码
jsetc@linux:~/jsetc/210/day14$ umask 0002
文件掩码取反再相与得到
修改文件掩码: umask + 想要修改的值 使用文件掩码取反后和文件权限相与得到最后的文件的权限
ll查看权限
- #include
- #include
- #include
- #include
-
- int main(int argc, char const *argv[])
- {
- int fd = open("1.txt",O_RDWR|O_EXCL);
- if(fd == -1)
- {
- perror("open");
- }
- perror("open");
- return 0;
- }
-
头文件:
#include
由字面意思,unistd.h是unix std的意思,是POSIX标准定义的unix类系统定义符号常量的头文件,
包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数。
原型:
ssize_t read(int fd,void *buf,size_t count)
功能:
对一个文件进行读取
参数:
fd:目标文件描述符 --------》对哪个文件进行读取
buf:存放读取到的数据------》读取到的数据存放的地址
count:读多少
返回值:
成功返回读取到的字节数
失败返回-1
读到末尾返回0
注意:但是最后一次read时如果文件剩余字节不够count,读到文件末尾时返回已经读到的字节个数 ,再一次读取时返回0
- #include
- #include
- #include
- #include
- #include
-
- int main(int argc, char const *argv[])
- {
- int fd = open("1.txt",O_RDONLY);
- if(-1 == fd)
- {
- perror("open");
- return -1;
- }
- perror("open");
-
- char buf[1024] = {0};//要初始化哦,不然会有垃圾数据
- int ret;
- if(-1 == (ret = read(fd,buf,10)) )
- {
- perror("read");
- return -1;
- }
- perror("read");
- printf("%s\n",buf);
- printf("%d\n",ret);
- return 0;
- }
头文件:
#include
原型:
ssize_t write(int fd,const *buf,size_t count)
size_t 是 long int 类型
功能:
对一个文件进行写入操作
参数:
fd:文件描述符 ---------》对哪个文件操作
buf:要写入数据的地址--------》写入的具体数据
count:写入数据的大小
返回值:
成功返回写入的字节个数
失败返回-1
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int main(int argc, char const *argv[])
- {
- int fd = open("1.txt",O_RDWR|O_APPEND);
-
- if(-1 == fd)
- {
- perror("open");
- printf("errno = %d\n",errno);
- return -1;
- }
- perror("open");
-
- char buf[] = "hello world\n";
- int ret;
-
- if(-1 == (ret = write(fd,buf,strlen(buf))))
- {
- perror("write");
- return -1;
- }
- perror("write");
- printf("%d\n",ret);
-
- if(-1 == write(fd,"zhangriyu?",9))
- {
- perror("write");
- return -1;
- }
-
- return 0;
- }
头文件:
#include
#include
原型:
off_t lseek(int fd,off_t offset,int whence);
off_t类型用于指示文件的偏移量,常就是long类型
功能:
操作读写指针,对读写指针偏移
参数:
fd:文件描述符
offset:如何偏移,偏移多少
如果该数为负数,代表向左进行偏移,如果偏移出了文件的开头,会报错返回
如果该数为正数,代表向右偏移,如果偏移出了文件的末尾,会扩大文件,用‘\0’来 填充,那么此类文件被称为---空洞文件--
注意:如果偏移后没有对其进行任何写入操作,内核会认为该偏移无效,不会扩大文件 大小
whence:基准位置 ---》根据哪一个位置进行偏移
SEEK_SET:根据文件开头进行偏移
The file offset is set to offset bytes.
SEEK_CUR:根据用户当前位置进行偏移
The file offset is set to its current location plus offset bytes.
SEEK_END:根据文件末尾进行偏移
The file offset is set to the size of the file plus offset bytes.
返回值:
成功:返回偏移的字节个数(根据文件开头来定)
失败:返回-1
练习:先对一个文件进行写入helloworld,然后从这个文件将helloworld读出来,打印到终端上。
#include #include #include #include #include #include int main(int argc, char const *argv[]) { int fd = open(argv[1], O_RDWR|O_CREAT,0664); if(fd == -1) { perror("open"); return -1; } perror("open"); char buf[] = "hello world"; if(-1 == write(fd, buf, strlen(buf))) { perror("read"); return -1; } int ret; if(-1 == (ret = lseek(fd,0,SEEK_SET))) { perror("lseek"); return -1; } perror("lseek"); printf("%d\n",ret); char buf1[100] = {0}; if(-1 == read(fd,buf1,11)) { perror("read"); return -1; } perror("read"); printf("%s\n",buf1); return 0; }
#include #include #include #include #include int main(int argc, char const *argv[]) { if(argc != 3) { printf("输入错误\n"); return -1; } int fd = open(argv[1], O_RDONLY); if(-1 == fd) { perror("open"); return -1; } perror("open"); int fd1 = open(argv[2], O_WRONLY|O_CREAT,0664|O_TRUNC); if(-1 == fd1) { perror("open1"); return -1; } perror("open1"); char buf[1024] = {0}; while(1) { ssize_t ret = read(fd,buf,1024); if(ret == -1) { perror("read"); return -1; } if(0 == ret) { printf("读到文件末尾了,开始写入----\n"); break; } if(-1 == write(fd1,buf,ret)) { perror("write"); return -1; } } close(fd); close(fd1); return 0; }