Android系统开发(6)——Linux底层输入输出

一、操作系统的体系结构

计算机是由一堆硬件组成的,操作系统是为了有效的控制这些硬件资源的软件。操作系统除了有效地控制这些硬件资源的分配,并提供计算机运行所需要的功能之外,为了提供程序员更容易开发软件的环境,操作系统还提供了一整组系统调用接口。

如上图所示,最中间的是硬件,操作系统是由内核和系统调用接口组成,其中内核是直接操作硬件的,内核提供了对这些硬件资源的控制和进程管理,系统调用接口向上提供了统一的调用接口方便开发人员调用。最上层就是应用程序,在应用程序中调用系统接口就能实现对硬件的操作。

二、Linux I/O系统


如上图Linux的I/O系统结构图,内核层有一个虚拟文件系统,就是使用标准的c类库封装的api,所以我们要操作文件系统只需要调用这里的api即可。

三、I/O的操作过程

1、打开文件
一个应用程序通过要求内核打开相应的文件,宣告他要访问一个I/O设备,内核返回一个非负整数,叫描述符号(Descriptor)【文件唯一标识】
2、读写文件
读:从文件拷贝n>0个字节到存储器(内存)
写:从存储器(内存)拷贝n>0个字节到文件
3、改变文件位置
4、关闭文件
对于内核而言,所有打开文件都由文件描述符引用。
文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读写一个文件时,用open或create返回的文件描述符fd标识该文件,将其作为参数传送给read或write.而流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装, 它的优点是带有I/O缓存

Linux支持各种各样的文件系统格式,如ext2、ext3、reiserfs、FAT、NTFS、iso9660等等,不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式,然而这些文件系统都可以mount到某个目录下,使我们看到一个统一的目录树,各种文件系统上的目录和文件我们用ls命令看起来是一样的,读写操作用起来也都是一样的,这是怎么做到的呢?Linux内核在各种不同的文件系统格式之上做了一个抽象层,使得文件、目录、读写访问等概念成为抽象层的概念,因此各种文件系统看起来用起来都一样,这个抽象层称为虚拟文件系统(VFS,Virtual Filesystem)


四、Linux底层输入输出

我们可以去GNU下载libc的源代码和帮助文档(源码下载地址:http://ftp.gnu.org/gnu/glibc/)
打开和关闭文件流
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
        //open file
        if(argc<2){
                printf("please input filename\n");
                exit(1);
        }else{
                int fd;
                umask(0000);
                fd = open(argv[1], O_RDWR|O_CREAT, 0666);
                if(fd < -1){
                        printf("error\n");
                        exit(1);
                }else{
                        printf("success=%d\n", fd);
                        close(fd);
                        printf("closed\n");
                }
        }
        return 0;
}
读文件(写文件的过程和读文件类似)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
        //open file
        if(argc<2){
                printf("please input filename\n");
                exit(1);
        }else{
                int fd;
                umask(0000);
                fd = open(argv[1], O_RDWR|O_CREAT, 0666);
                if(fd < -1){
                        printf("error\n");
                        exit(1);
                }else{
                        printf("success=%d\n", fd);
                        char buf[1024];
                        memset(buf, 0, 1024);
                        int returnum = read(fd, buf, 1024);
                        if(returnum != -1){
                                printf("buf=%s\n", buf);
                        }else{
                                printf("read error\n");
                                exit(1);
                        }
                        close(fd);
                        printf("closed\n");
                }
        }
        return 0;
}


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。