前言
“裸奔”层次:不带操作系统的编程
特点:
简单,粗暴应用层直接操作硬件(寄存器、IO口…)
缺点:
开发应用、要能搞懂原理图
了解硬件的细节
不能同时运行多个任务:单任务运行
带“OS”的编程
特点:
开发应用、主要实现应用的逻辑实现
不需要关心底层硬件的实现细节
可以支持多任务运行、并发
缺点:
API(application interface) 太多了
API的实现(功能)可能不是我们想要的
OS:Operating System 操作系统。是直接运行在“裸机”的最基本的系统软件,任何软件/应用程序都必须要在操作系统的支持下才能正常运行。
操作系统:
windows x86/xp/win8/win10/win11
linux ubuntu/centos/redhat/kali
mac
IOS
Android
鸿蒙
unix
Linux操作系统下进行开发应用软件,就是调用Linux操作系统为我们提供的系统的API函数接口去操作硬件。或者是说用Linux提供的服务来完成linux下的一些开发。
Linux文件系统
在linux下面,一切皆文件。在linux 下面操作任何东西,其实都是通过操作文件来实现的,通过文件的接口实现
文件:
文件属性:inode(编号),inode----> 文件内容…
文件内容:文件的实际存储的内容
文件在Linux下的操作过程:
硬链接(找文件名)---->inode
linux内核
操作过程:struct file —> struct inode —> 硬件上的inode —> 文件内容
linux为了屏蔽文件操作的具体实现细节,它会为进程创建一个“进程文件表项
进程文件表项
每一个应用都会有一个进程文件表项,保存进程打开的文件的sturct file结构体指针,相当于是一个struct file *的数组(集合),打开一个文件,只需要返回一个下标给我使用就可以了
linux提供系统操作函数:open、write、read、close…以上这些函数都是称为:“系统IO”
系统IO:操作系统所提供的对于文件的输入输出的函数接口
linux系统IO的应用
第一步:打开文件:
OPEN(2) System calls OPEN(2)
NAME
open, creat - 打开和/或创建一个文件
SYNOPSIS 总览
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
/*
@打开一个文件
@pathname:需要打开的文件的名字(路径+文件名+扩展名)
@flags:标志位
打开方式:
O_RDONLY 以只读方式打开
O_WRONLY 以只写方式打开
O_RDWR 以可读可写方式打开
@return 成功返回文件的struct file指针在进程文件表项中的下标(文件描述符),失败
返回-1
*/
int open(const char *pathname, int flags, mode_t mode)
/*
@打开一个文件
@pathname:需要打开的文件的名字(路径+文件名+扩展名)
@flags:标志位
打开方式:
O_RDONLY 以只读方式打开
O_WRONLY 以只写方式打开
O_RDWR 以可读可写方式打开
@mode:
当你使用了O_CREAT标志的时候,请你填写此参数
mode用来设定文件的权限的
当然最终文件权限取决umask和填写权限运算
@return 成功返回文件的struct file指针在进程文件表项中的下标,失败返回-1
*/
第二步:对文件进行操作
READ(2) Linux Programmer's Manual
READ(2)
NAME
read - 在文件描述符上执行读操作
概述
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
/*
@从一个指定的文件描述符中(fd)读取count个字节的数据存储到buf所指向的
内存空间中
@fd:
file id 文件描述符,一般由open函数返回。需要是有效文件描述符
@buf:
void * 类指针,用来存储读取到的字节的内存空间的首地址指针
@count:
个数,表示需要读取多少个字节
@return:
成功:实际读取到的字节数量
失败:返回-1
*/
写入内容:
WRITE(2) Linux Programmer's Manual
WRITE(2)
NAME
write -在一个文件描述符上执行写操作
概述
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
/*
@往一个指定的文件描述符中(fd)写入buf所指向的内存空间中的count个字节
的数据
@fd:
file id 文件描述符,一般由open函数返回。需要是有效文件描述符
@buf:
void * 类指针,用来存储写入数据的存储内存空间的首地址指针
@count:
个数,表示需要写入多少个字节
@return:
成功:实际写入到的字节数量
失败:返回-1
*/
第三步:关闭文件
CLOSE(2) Linux Programmer's Manual
CLOSE(2)
NAME 名字
close - 关闭一个文件描述符
SYNOPSIS 总览
#include <unistd.h>
int close(int fd);
/*
@fd : 需要关闭的文件描述符
@return 成功返回0,失败返回-1
*/
其他操作:设置偏移量
有时候咱们想在文件中间某个指定的文件插入内容
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
/*
作用:
设置一个文件的光标偏移量
返回值:
实际偏移字节数量,失败返回-1
fd:
需要进行光标偏移的文件描述符。
offset:
off_t类型 光标需要偏移的字节数量。可以为正也可以为负
如果为正数,则表示光标向文件末尾的方向偏移
如果为负数,则表示光标向文件头的方向偏移
whence:
SEEK_SET
The file offset is set to offset bytes.
从文件开头的位置进行偏移
SEEK_CUR
The file offset is set to its current location plus off‐
set bytes.
从当前位置开始进行偏移。
SEEK_END
The file offset is set to the size of the file plus off‐
set bytes.
从文件末尾开始进行偏移
@return 成功返回实际偏移的字节数,失败返回-1
*/
注意:当一个文件被成功打开之后,光标所属位置,在最开始的位置。除非打开的时候使用了O_APPEND,那么光标就会移动到文件内容的最末尾
注意:当文件没有被关闭,那么进行write/read操作会改变光标位置,光标的偏移会被read/write的
返回值影响。