IO的基本函数
c语言阶段的文件操作
FILE *fopen(const char* path,const char *mode)
FILE* :文件流指针类型
path:需要打开哪一个文件。可以带路径,若不带路径,则在当前的目录下寻找
mode:
r :以读的方式打开,如果打开的文件不存在,则报错
r+ : 以读写方式打开,如果打开的文件不存在,则报错
w :以写的方式打开,如果文件不存在,则创建。如果文件存在,则将文件截断,文件流指针指向文件头部(即:删除原有内容)
w+ :以读写的方式打开,如果文件不存在,则创建。如果文件存在,则将文件截断,文件流指针指向文件头部(即:删除原有内容)
a :以追加方式打开,如果文件不存在则创建。如果文件存在,则将文件流指针的位置指向当前文件的尾部,不能读。
a+:以追加方式打开,如果文件不存在则创建。如果文件存在,则将文件流指针的位置指向当前文件的尾部,当前的a+是支持读的
size_t fread(void *ptr,size_t size,size_t nmemb, FILE * stream)
ptr: 将fread读到的内容保存在ptr里面
size:块的大小
nmemb: 块的个数
stream :文件流指针
返回值:成功读到的块的个数
常用的用法:将块的大小指定为1,块的个数就是ptr的内存空间大小
size_t fwrite(const void* ptr,size_t size,size_t nmemb,FILE * stream)
ptr:写的数据放到ptr当中
size:块的大小
nmemb:块的个数
stream:写到哪里去,文件流指针
返回值:返回成功写入的块个数
常用用法:将size指定为1,然后返回值就是成功写入的字节数量
int fseek(FILE* stream,long offet,int whence)
stream:文件流指针
offset:偏移量,针对第三个参数
whence : 需要将文件流指针定位到哪个位置
- SEEK_SET
- SEEK_END
- SEEK_CUR
int fclose(FILE* fp)
fp: 文件流指针
成功返回 0
系统调用的文件操作:
int open(const char* pathname,int flags, mode_t mode)
pathname:要打开的文件路径
flags:以何种方式打开
必须要指定的三个参数当中任选一个
O_RDONLY :以只读的方式打开
O_WRONLY :以只写方式打开
O_RDWR :以读写方式打开
这三个常量,必须指定一个且只能指定一个
可以附加的参数
O_CREAT :如果要打开的文件不存在则创建
O_TRUNC :打开文件之后截断文件
假如 文件 已经 存在 , 且是 一个 普通 文件 ,打开 模式 又是 可写(即 文件 是 用 O_RDWR 或 O_WRONLY 模式 打开 的) ,就把 文件 的 长度 设置 为 零 , 丢弃 其中 的 现有 内容.若 文件 是 一个 FIFO 或 终端设备 文件 , O_TRUNC 标志 被忽略.
O_APPEND : 以追加方式
需要组合使用的时候,可以采用按位或的方式 |
mode 设置文件读写权限
返回值:成功,返回大于0的整数 》文件描述符
失败,返回-1
ssize_t write(int fd,char* buf,size_t count)
fd:文件描述符
buf:写入的数据
count: 写入数据的大小
ssize_t read(int fd,char* buf,size_t count)
fd:文件描述符
buf : 数据存储的空间
count:最大读多少
off_t lseek (int fd, off_t offset, int whence )
fd:文件描述符
offset :偏移量
whence : (偏移到哪里去)
- SEEK_SET
- SEEK_END
- SEEK_CUR
close(int fd)
fd :文件描述符
当我们使用fwrite函数进行写操作的时候,其实是先写到缓冲区,然后当刷新缓冲区,才通过_IO_FILE当中保存文件描述符信息将写到缓冲区当中的内容写到文件中去
当使用文件流指针操作文件的时候,一定要考虑读写缓冲区的问题。如果当我们往一个文件当中写数据的时候,程序崩溃了,有可能就会导致使用文件流指针写入的数据丢失
当使用文件描述符的时候,就没有这个问题,但是由于立即读取,立即写入的操作是非常耗费性能,所以在写程序当中,一些不重要的数据可以采用文件流指针操作。
文件描述符:是fd_array[ ]的下标,分配规则是最小未占用原则
文件流指针:在c语言库中,使用结构体_IO_FILE封装文件描述符,使用_fileno这个变量保存文件描述符的值
重定向:
本质:将newfd文件描述符拷贝oldfd文件符
每个文件描述符都是一个内核中文件描述信息数组的下标,对应有一个文件的描述信息用于操作文件,而重定向就是在不改变所操作的文件描述符的情况下,通过改变描述符对应的文件描述信息进而实现改变所操作的文件
命令操作
> 清空重定向
>> 追加重定向
函数:
int dup2(int oldfd,int newfd)
oldfd和newfd 都是文件描述符
如果oldfd是一个无效的文件描述符,newfd在重定向的时候,并不会关闭,调用dup2函数会失败
静态库 和动态库
静态库:
win环境下的后缀是.lib
Linux环境下的后缀是 .a 前缀是lib 例如 libprint.a
静态库会将编译的代码当中的所有函数的代码全部编译到静态文件当中去。
如果程序链接静态库生成可执行程序的时候,会将静态库当中所有的代码全部编译到可执行程序当中去,当程序执行的时候,就不需要依赖静态库了
静态库的生成与使用
静态库的生成
注意:生成静态库的时候,是使用.o文件来进行编译生成
ar -rc lib[库文件名称].a [文件].o
静态库的使用:
-L [path] 指定库的路径
eg: -L . 在当前目录下查找
-l[库文件名称(去了前缀和后缀名称)] :可以指定链接的库文件是哪一个
eg: gcc main.c -o main -L . -lprint
动态库:
win环境下的后缀是.dll
linux环境下的后缀是.so ,同样前缀是.lib
当我们编译一个程序依赖一个动态库的时候,可执行程序会将动态库当中的函数保存在符号表中,当程序运行的时候,操作系统会加载动态库,从而使可执行程序可以通过符号表在动态库当中找到对应函数的实现。
动态库的生成与使用
动态库的生成:
-shared :生成共享库的命令行参数
-fPIC :产生与位置无关的代码
动态库的使用:
-L [path] :指定动态库的搜索路径
-l [动态库的文件名称]
如果一个可执行程序依赖一个动态库,在程序运行的时候,程序正常找到依赖动态动态库的方式有两种
1、将动态库放到当前可执行程序的目录底下
2、在环境变量当中去设置动态库的搜索路径,设置环境变量LD_LIBRARY_PATH