文章目录
- 文章目录
- 前言
- 一、文件操作
- 标准IO
- 文件IO
前言
文件IO: 如何通过代码去操作文件,包括创建、删除、修改等、
多任务:多个进程同时工作,完成同一个任务
特点:运用大量的系统提供的函数,实现我们的功能。
库:library
C库 pthread库,包括静态库和动态库的制作
一、文件操作
原理: 文件放在硬盘--硬件,由系统管理
app--->c库--->os 操作系统-->文件/硬件
c库: 是标准的,通用的---独立于os
linux 系统它使用的 GLIBC库, 不是标准的c库
他是c库的超集, so ,我们linux 有两套访问文件接口
1.标准IO 标准c库提供的
通用的, 只针对普通文件
2.文件IO linux特有的
linux除了支持普通文件外,还支持很多特有的文件,因为linux把一切都看作了文件
1.标准IO
操作: 创建 删除 打开fopen 关闭fclose 读fread 写fwright
读: 将文件 读取到 内存中 修改
写: 将内存数据写入到物理文件中
1.打开文件fopen
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
path:文件路径,可以相对,也可以绝对地址
mode: 打开权限
"r": 只读 readonly
"r+": read and write
"w": 不存在则创建,存在则清零文件,只写方式打开
"w+": 比 w增加了read权限,首先清空
"a": append, writeonly,以追加方式打开,不存在则创建
"a+": 增加read
返回值:
success 返回文件指针,以后read write 都通过改指针进行
failed NULL
2. #include <stdio.h>
写入文件
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
ptr:存放了要写入的数据
stream:文件指针
size,nmemb : 你要写入多少个块(nmemb),每个快有多大(size)
返回值:
实际写入的块个数 ,如果出错 返回值小于nmemb
3.fread
读: 从物理文件读取内容到 内存
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:存放数据的buf,你分配的空间
stream:上面打开的文件描述符
size, nmemb: 我们一次要读取很多块(num member block),每块多大(size B)
返回: 实际读取的 块个数
0: 1) 没有数据了 2)出错了
你要使用 int feof(FILE *fp); 0-没有结尾 其他-结尾
int ferror(FILE *fp) 0-没有出错 其他-出错了
4.fclose
#include <stdio.h>
int fclose(FILE *stream);
stream: 文件指针
return:
0-success
-1/EOF- failed
5.fgets fputc fgets, 他们是基于 fwrite fread 实现的
char fgetc( FILE *fp ) 从文件中读取一个字符出来
int fputs (char ch, FILE *fp) 向文件中写入一个字符
fgets : 实现从文件中读取 一行数据
char *fgets(char *buf, int bufsize, FILE *fp)
6. 文件位置指针(int fops)
问题: 以前为什么连续读/写,可以成功 因为 文件内部有这么一个指针
fread / fwrite 会自动调整 位置指针
ftell () ---获取文件 当前位置指针的 位置(相对于文件头部偏移量)
long ftell( FILE *fp );
返回值: >=0 success
-1: failed
fseek () ---改变文件指针位置
int fseek(FILE *stream, long offset, int whence);
whence: SEEK_SET 从头部开始衡量,offset >=0
SEEK_CUR 从当前位置衡量 offset 可正可负
SEEK_END 从尾部开始衡量,offset<=0
返回值:0-success -1:failed
offset 偏移量
7.errno
FILE *fopen (char *path, char *mode);
可能出错, 比如 文件不存在, 比如 权限不满足 ......
当你 fopen 失败的时候, 你可能想知道 错误的具体原因
errno 编译器帮你添加,你不需要定义,但要添加#include <errno.h>
linux 系统引入了一个 全局的整型变量errno
当系统函数失败的时候,系统函数会把失败的原因存放在errno
2.文件IO
1.open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
pathname,文件路径
flags: 他是一个32bit的整数,
每一个bit表示文件的一种属性,比如 某个bit置一表示文件可写,置零表示不可写
O_RDONLY 只读
O_WRONLY 只写
O_RDWR: 读写
上述三个必须包含一个.
O_APPEND: append-追加
O_CREAT: 创建
可以指定一个权限, mode指定权限
只有flags参数中包含O_CREAT,mode才能使用
0660,表示这是一个 八进制 0x12 23 023
O_TRUNC: 如果文件存在,则清空
返回值:
成功返回一个 文件描述符, 正数
失败: -1, errno
2.write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
fd:文件描述符
buf: 存放数据的buf
counte:你要求写入的大小B
返回值:
success: 实际写入的大小
-1:失败,errno
3.read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符
buf: 数据存放的位置
count:你要求读多少数据,B
返回值:
实际读取的大小 0-表示文件结束
-1 failed,errno
4.close
#include <unistd.h>
int close(int fd);
返回值: succes-0
-1 failed ,errno
5.lseek 获取/设置 文件指针的位置
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
fd:文件描述符
offset:偏移量
whence:
SEEK_SET: 从头部开始计算 offset>=0
SEEK_CUR: 从当前位置计算 可正可负
SEEK_END: 从尾部开始计量
返回值:
成功 返回的是 当前位置距离头部的偏移量 >=0
失败 -1,errno
获取文件大小:
fsize=lseek(fd,0,SEEK_END);
6.unlink ,删除文件,独立于标准IO 和文件IO
int unlink(char *path);
3.目录
打开目录:
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
name,目录路径
返回值:
指向该目录的一个指针,后续访问该目录都是使用改指针
NULL, errno
读取目录:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
dirp:opendir的返回值
返回的是 一个目录项 指针:
如果你想获取所有的内容,你就 不断的读,只到读完所有(NULL)
NULL, 读完了,出错了
struct dirent {
ino_t d_ino; inode number
off_t d_off; not an offset; see NOTES
unsigned short d_reclen; length of this record
unsigned char d_type; type of file :
记录了该 目录项 的类型:
普通文件,目录, 软连接, 块设备,字符设备 未知
DT_REG DT_DIR DT_LNK DT_BLK DT_CHR DT_UNKOWN
char d_name[256]; filename 目录项 名字
};
关闭目录:
#include <dirent.h>
int closedir(DIR *dirp);
返回值:
0-success
-1: errno
以上是我的学习笔记,难免有出错的,望包涵,欢迎大家评论区留言