open()函数,打开一个文件,第一个参数,打开文件的路径与文件名,默认在当前路径。第二个参数,打开文件的方式(可一次指定多个参数,用"|"隔开),第三个参数,如果要打开的文件不存在且第二个参数表明不存在就创建文件,第三个参数为新创建文件的权限。
第二个参数有这几个常用的:
O_CREAT:如果要打开的文件不存在,则创建该文件
O_RDONLY:打开的文件有可读权限
O_WRONLY:打开的文件有可写权限
O_RDWR:打开的文件具有可读可写权限
O_TRUNC:打开文件时清空文件内容
O_APPEND:以追加方式打开文件
返回值:成功返回文件描述符,失败返回-1;
)
打开当前目录下的test.txt文件,打开的文件具有可读可写权限,如果文件不存在则创建该文件且文件的权限为0664.
write()函数,往文件内写内容。第一个参数,文件描述符,往哪个文件里写入;第二个参数,字符串,要写入的内容;第三个参数,期望写入多少个字节。
返回值:实际写入的字节数。
打开一个文件,往文件里写入字符串"i like linux!"。
lseek()函数
lseek()函数,调整当前文件的指针,每次对文件进行操作后,指针就会跳转到操作结束的位置,下一次对文件进行操作时就从该位置开始(如写操作,第一次写入一个字符串,指针指向字符串的结尾,这使要从文件读内容时就从该位置开始)。
第一个参数:文件描述符,对哪个文件进行操作;
第二个参数:从whence指定的位置,向前或者向后移动指定字节数;
第三个参数:
SEEK_SET:调到文件起始位置
SEEK_CUR:调到文件当前读写的位置
SEEK_END:调到文件末尾位置
返回值:返回当前读写位置相对于文件开始位置的偏移量(字节)。
执行写操作后,调整文件指针到文件最开始的位置。
read()函数,从文件中读取内容。
第一个参数:文件描述符,从哪个文件中读取内容;
第二个参数:读取到buf内;
第三个参数:期望读取多少个字节;
返回值:实际读到的字节数。
将文件内容读到字符串buff里。
dup2()函数,将旧的旧的文件描述符的内容拷贝到新的文件描述符里面,两个文件描述符指向指向同一个文件。
实际上就是往文件里面写内容,执行echo命令时,实际上就是往显示器打印字符串,从文件的角度来看就是往1号文件(标准输出)里写入了"hello world"字符串。在增加重定向符号时,就相当于关闭当前进程的1号文件,然后在当前目录打开重定向符号后面的文件名,如果没有则创建,根据文件描述符分配规则,新打开的的文件的文件描述符会是1,然后还是将字符串写入1号文件,最后关闭该文件,重新打开标准输出,标准输出文件描述符还是1。
追加重定向实际上就是以追加方式打开文件。
Linux使用ext2文件系统,磁盘被分为好多个块,文件存放在块中。为了提高效率,文件并不一定存放在连续的块中,所以文件被分别存放在哪些块里需要被保存起来。并且一个文件不只有文件内容,还有文件的属性信息,这些东西不属于文件内容,但是也要被保存起来,由此就产生了inode。
每一个对应一个唯一的inode编号,inode中保存该文件的所有属性信息以及该文件被保存在哪些块中,所用通过inode可以找到文件具体存放在磁盘的那个位置,从而对文件进行操作。
链接就是将A文件指向B文件,对A文件进行操作就相当于对B文件进行操作
硬链接本质上没有创建新的文件,只是有一个文件名,它的inode与他连接的文件的inode一样。
命令
ln 原文件 要创建的链接文件
两个文件的inode一样。
软连接本质上是创建了一个新的文件,该文件里保存了链接对象的文件名与路径。
命令
ln -s 原文件 要创建的链接文件
静态库的命名
lib[库名称].a
假如一个库的文件名为libhello.a,那么这个库的实际名称为hello
这里我写了三份代码,myprint.h里面放函数的声明,myprint.c里面放函数的实现。
print.c里面调用函数。
要把文件生成库文件,首先要将所有的.c文件编译为.o文件,然后将.o文件进行打包生成静态库。
gcc -c *.c
将所有的.o文件打包成静态库
ar -rc libprint.a myprint.o print.o
然后创建mylib文件夹,将头文件与静态库放到mylib文件下。
这样其他程序要使用该头文件与其头文件内定义的函数,就可以在编译时指定头文件查与静态库的路径路径,然后就可以直接使用了。
可以看到,我当前写的程序没有包含stdio.h,也没有定义Print函数,但是包含了myprint.h。只要在编译时指定头文件与要使用的库的路径,就可以正常使用了。
//-I
指要包含的头文件的路径,这里头文件在当前目录的mylib/include路径下
//-L
指库文件路径,这里库文件在当前目录的mylib/lib路径下
//l
指要用的库的名字,注意这里的名字要去除前缀与后缀。
//-static
指静态链接,即链接的是一个静态库
动态库的命名与静态库的名称稍有不同。
lib[库名称].so
先将所有的.c文件生成.o文件。
gcc -fPIC -c *.c
-fPIC命令行标记告诉GCC产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。
然后将所有.o文件生成libprint.so动态库文件。
将生成的动态库与.h文件放在mylib.so文件下。
编译时链接动态库
但我们在运行时却发现不可以运行,因为链接动态库时程序在运行时遇到库函数才会把库函数加载到内存里运行,而我们只是在编译时加入动态库的路径,程序运行时并不知道动态库在哪里。
这个环境变量是指程序在运行时找动态库的路径,只需要把我们的动态库加进去就可以了。