Linux 中的文件系统
基本结构
基本结构如下所示,设备被当做一个文件来进行操作,所以称之为设备文件系统。在设备文件系统中,系统为用户态提供了一系列的操作API结构,设备在文件系统中/dev目录生成一个访问节点。
访问接口
int open(char* dev, tags)
int close(int)
int read(int fd);
int write(int fd,xxx);
int ioctl(int fd,xxxx);
int lseek(int fd,xxxx);
实际以上是一些标准的访问C接口,也就是VFS文件系统向上层提供的统一的访问内核设备的接口。VFS文件系统 这篇的图比较形象的画出了VFS文件系统结构,如下:
文件基本读写
文件被看成是一个”流”, 流是一组连续的数据,具有开头和结尾,并且使用游标指示当前位置。流中包含的数据可能来自内存(MemoryStream)、文件(FileStream)、或TCP/IP套接字(NetworkStream)流一般可以支持3种类型的操作
- 读取,即将数据从流传入到数据机构(如字符串或字节数组)中
int fgetc( FILE *fp);
/*
从流中读取一个字节
*/
char* fgets(char* s, int size, FILE* stream)
/*
1.从文件流中读取size个字节的内容到s中
2.直到出现换行字符、读到文件尾或是已读了size-1个
字符为止,最后会加上NULL作为字符串结束。
*/
int fread(void* ptr, size_t size, size_t n, FILE* s)
/*
1. 从流s中读取n个数据块,每个数据块的长度是size,存入ptr中
2. 所以读出的长度是n*size个byte
3. 返回的参数代表读取的数据块个数,注意不是字节数
4. 本函数一般用于二进制模式打开的文件中
*/
int fscanf(FILE *fp, char *format, e1,e2,......en);
/*
1. 格式化读取流中数据到 e1-ek中
2. 适合字符模式
3. 和scanf类似,实际上scanf是stdin文件流的输入函数
*/
- 写入,将数据写入到流中
int fputc(char ch, FILE *fp);
/*
1. 写入ch到fp流的末尾
*/
char * fputs(char *str, FILE *fp);
int fwrite(char * buf, unsigned size, unsigned n, FILE *fp);
/*
size 每个数据块的字节数, n个数据块.
*/
int fprintf(FILE *fp, char *format, e1,e2,......en);
/*
1. 格式化输入到文件流中
2. format 格式内容,e1-ek是输入的参数
3. 类似于printf,实际上printf的输出流是stdout
*/
- 流中查询, 查找和修改你在流中的位置
int fseek(FILE *fp, long offset, int from);
/*
1. from 是查询的起始点,
2. SEEK_SET 0 从文件头开始
3. SEEK_CUR 1 从文件内部指针当前位置开始
4. SEEK_END 2 从文件尾开始
5. offset 是from起始的偏移长度,最终定位到from+offset位置。
*/
- 文件控制,控制文件流
/*用来侦测是否读取到了文件尾,如果已到文件尾则返回非零值,其他情况返回0。*/
int feof(FILE* stream);