int open(const char *pathname, int flags);
flag:(O_RDONLY,O_WRONLY ,O_RDWR )| ( O_APPEND, O_CREAT )
前面三选一,后面可选。
如果是CREAT表示有就执行正常操作,打开失败则创建文件,需要有第三个参数mode,是创建的文件权限。
//仅在文件不存在时可以创建并append数据到文件末尾,若存在则打开失败
int fd = open("xx", O_RDWR|O_APPEND|O_CREAT|O_EXCL, 0644);
char* str = "hello write\n";
write(fd, str, strlen(str));
如果使用O_WRONLY,往已存在的文件里写,不会清空原数据,要加O_TRUNC。
关闭文件
int close(const char *pathname);
操作系统为了管理文件,将文件用 struct_file描述起来,用链表数据结构将结构体组织起来。
进程需要一对多的找到属于进程打开的文件,在PCB里有files_struct这么一个结构,其中有一个指针数组保存着文件表指针,而其数组下标就是文件描述符。
查看系统限制最大文件描述符个数:proc/sys/fs/file-max
系统允许最大文件描述符,由内存大小决定
ulimit -a 查看用户级限制的文件描述符个数,可以手动调整
系统默认打开三个文件描述符作为标准输入输出错误。
ctr + D 相当于从键盘输入文件结束标记EOF
一个进程两次打开同一个文件,创建新文件表,不创建v结点表。
子进程继承父进程文件描述符,文件表引用计数+1.
##C库FILE结构和文件描述符
C语言中使用的是文件指针而不是文件描述符做为I/O的句柄.
文件指针指向FILE结构。FILE结构包括一个缓冲区和一个文件描述符值.而文件描述符值是文件描述符表中的一个索引.从某种意义上说文件指针就是句柄的句柄。流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装, 它的优点是带有I/O缓存。
真正的数据是在磁盘上存储,磁盘又是一个分盘面,扇区的设备,常见八个扇区为一块。为了操作系统能够准确定位数据读写位置,引入ionde节点。
inode节点存放了文件block位置信息,和文件字节数等重要的文件信息。
想找一个文件的3步骤,通过文件名映射到inode号,读取inode节点信息,找到文件块位置。
inode节点是用来索引文件的,其自身为了存储一些信息必然也需要占空间。操作系统自动划分一个inode区。
Unix支持多个文件名指向同一个inode号码,这样修改文件内容会影响到所有的文件。但是删除一个文件名,不影响其他文件名访问。因为其中利用了引用计数原理。
软链接更像是快捷方式。为A文件创建一个软链接B,则A B有自己的inode节点,但是B文件的内容是A文件的路径。因此在访问B时就自动导向A,且B依赖于A,A没了B打开报错。
之所以叫做静态,是因为静态库在链接阶段的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。
静态函数库对开发者来说还是很有用的,例如你想把自己提供的函数给别人使用,但是又想对函数的源代码进行保密,你就可以给别人提供一个静态函数库文件。
静态库将多个目标文件捆绑,形成一个库文件,对调用者提供服务。
ar -cr libxx.a
xx 是静态库名
nm xx 查看静态库
gcc -L库文件路径 -l库名
objdump -dS 查看可执行文件的汇编形式
也称共享库,linux下后缀是.so,windows是dll。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来
共享函数库文件必须放在一些特定的目录里,这样通过系统的环境变量设置,应用程序才能正确的使用这些函数库。
gcc -fPIC -shared -o libxx.so
fPIC :位置无关代码??
shared : 生成动态库.
链接动态库
首先将库文件放在/usr/lib 目录下
gcc -L 库文件路径 -l库名
-L 在编译时告诉编译器库的路径,但在运行时系统是去ld.so.conf.d下去找库的。
方案2:提示找不到动态库时!!
不想将动态库放到/usr/lib,可以将库文件路径加入到环境变量里。
增加一个配置文件在 /etc/ld.so.conf.d/ 下,配置文件中写入库路径
echo pwd > /etc/ld.so.conf.d/xx.conf
ldconfig 刷新配置文件
ldd 可执行文件 #命令查看动态库链接错误
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib和/usr/lib;
cmake 连接时遇到skipping incompatible,说明版本不兼容,用objdump -p 查看动态库的编译版本发现问题。
指定32位编译器解决问题~
./configure CC=“gcc -m32” CXX=“g++ -m32”