一、文件与目录
1、文件概念:一组相关数据的有序集合
2、文件按类型分类:常规文件(ASCII码文件、二进制的文件)、目录、字符设备、块设备、有名管道、套接口、符号链接
3、获取文件/目录的属性信息:stat()/fstat()/lstat()
二、标准I/O
1、介绍
除了UNIX,在其他很多OS上也都实现了标准I/O库
由ANSI C标准说明
使用用户不必关心如何选择合适的块长度
在系统调用函数基础上构造,便于用户使用
标准I/O库及stdio.h头文件为底层I/O系统调用提供了一个通用的接口。
2、流和FILE对象
FILE指针:每个被使用的文件都在内存中开辟一个区域,用来存放文件信息,这些信息被保存在一个由系统定义的结构体中,该结构体取名为FILE。
流:所有的I/O操作仅是简单的从程序移进或者移出,这种字节流,就称为流。有文本流和二进制流两种。
3、文件缓
存分类
全
缓
存(fflush强制刷新一个流)、行缓存(\n或遇到一个终端时)、不带缓存(stderr)
4、stdin、stdout、stderr预定义的3个流,自动为进程所使用。
5、打开标准I/O流:fopen、freopen、fdopen,常用fopen
6、关闭标准I/O流:fclose
7、读写流结束判定:feof
8、读一个字符:getchar()等同于getc(stdin)、fgetc
9、输入一行-行I/O:gets、fgets
10、输出一行-行I/O:puts、fputs
11、读写流-二进制I/O:fread、fwrite
12、定位I/O流:ftell(当前位置)、fseek(设置位置)、fgetpos、fsetpos、rewind(设置流位置为文件开始)
二、文件I/O(不带缓冲)
1、文件描述符
顺序分配的非负整数
用以标识一个特定进程正在访问的文件
其他资源(socket、pipe等)访问标识
2、标准输入、标准输出、标准出错由shell默认打开,分别为0/1/2
3、出错处理:strerror()、perror()
4、打开或者创建一个文件:open()/creat()
5、关闭一个打开的文件:close()
6、读一个文件:read()
7、写一个文件:write()
8、文件定位:lseek()
三、系统调用和库函数
1、系统调用
用户空间进程访问内核的接口
把用户从底层的硬件编程中解放出来
极大的提高了系统的安全性
使用户程序具有可移植性
2、库函数
库函数为了实现某个功能而封装起来的API集合
提供统一的编程接口,更加便于应用程序的移植
四、I/O模型比较与区别
1、比较
I/O模型
|
文件I/O
|
标准I/O
|
缓冲方式 |
非缓冲I/O
|
缓冲I/O
|
操作对象
|
文件描述符
|
流(FILE *)
|
打开
|
open()
|
fopen()/
freopen()/fdopen()
|
读 |
read()
|
fread()/fgetc()/fgets()...
|
写 |
write()
|
fwrite()/fputc()/fputs()...
|
定位 |
lseek()
|
fseek()/ftell()/rewind()/fsetpos()/fgetpos()
|
关闭 |
close()
|
fclose()
|
2、fopen和open的对应关系
fopen("filepath", "r");
|
open("filepath", O_RDONLY);
|
fopen("filepath", "r+");
|
open("filepath", O_RDWR);
|
fopen("filepath", "w");
|
open("filepath", O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
fopen("filepath", "w+");
|
open("filepath", O_RDWR | O_CREAT | O_TRUNC, 0666);
|
fopen("filepath", "a");
|
open("filepath", O_WRONLY | O_CREAT | O_APPEND, 0666);
|
fopen("filepath", "a+");
|
open("filepath", O_RDWR | O_CREAT | O_APPEND, 0666);
|
3、文件I/O vs 标准I/O
文件I/O
| 标准I/O |
直接映射系统调用
|
封装了系统调用
|
操作对象是文件描述符
|
操作对象是FILE
|
用户态不带缓冲
|
用户态带缓冲
|
基本原语,使用相对麻烦但灵活
|
封装函数,便于使用但不灵活
|
五、静态库与动态库的分析
1、静态库
libpr.a是一个静态库
2、动态库(多-fPIC参数)
此时运行a.out报错,需指定库文件的路径
2.1、在执行的时候如何定位共享库文件
当系统加载可执行代码时,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loder)。
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的DT_RPATH段--->环境变量LD_LIBRARY_PATH
--->/etc/ld.so.cache文件列表
--->/lib/,/usr/lib目录找到库文件后将其载入内存。
方法1:放入/lib目录下 sudo cp ***.so /lib
方法2:
方法3:/etc/ld.so.cache见uboot录像6(不常用)
六、man手册
1、man 函数分册一共有7册
2、用法:man -f 函数名或命令名