函数原型:FILE *fopen(const char *path, const char *mode);
参数解释:
path:文件路径
mode:(打开方式)
返回值:
打开失败时,文件流指针返回NULL;成功时,返回文件流指针,做为操作文件的操作句柄.
int fclose(FILE *stream);
参数解释:
stream:文件流指针
补充:
feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
参数解释:
ptr:是指向要被写入的元素数组的指针(要写入的内容)。
size:是要被写入的块的大小,以字节为单位。
nmemb:是块的个数
stream:表示是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流(要写入的文件)。
返回值:
如果成功,则返回块的个数。失败或者到达文件末尾,则返回0
补充:
当块个数为1,写入的数据不足块的大小,返回值为0,为了防止这种情况,则可以将第二个参数写1,第三个参数写成一个数组的实际大小,则返回得是实际写入的字符串的长度。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数解释:
ptr:用于接收数据的内存地址
size:要读的每个块的字节数,单位是字节
nmemb:块的个数
stream:这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流(要读出的文件)。
返回值:
如果成功,则返回块的个数。失败或者到达文件末尾,则返回0
int fseek(FILE *stream, long offset, int whence);
参数解释:
stream:这是指向 FILE 对象的指针,该 FILE 对象标识了流。
offset:这是相对 whence 的偏移量,以字节为单位。
whence:3种情况
该函数的作用:可以向后任意跳转文件的当前读写位置,即使文件没有数据也可以跳转读写位置
c++中的标准库的输入输出:
他们都是FILE*结构体(文件流指针)
标准输入 | 标准输出 | 标准错误 | |
---|---|---|---|
文件描述符 | 0 | 1 | 2 |
宏定义 | STDIN_FILENO | STDOUT_FILENO | STDERR_FILENO |
标准库IO接口的操作句柄是:FILE*------文件流指针
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode)
这是一个不定参函数,当第二个参数为O_CREAT,则必须给出文件的权限,也就是第三个参数(八进制)
参数解释:
pathname:文件路径名
mode :当使用O_CREAT的时候有可能新建文件,因此需要指定文件的权限
mode & (~umask) =实际最终得到的文件权限
flags:选项标志
必选选项(并且只能选择其一):
可选选项:
例如:
w+:O_RDWR | O_CREAT |O_TRUNC
a: O_RDWR | O_APPEND | O_CREAT
返回值: 错误返回-1;成功返回一个非负整数—文件描述符—打开的文件的操作句柄
ssize_t write(int fd, const void *buf, size_t count);
参数解释:
fd:open返回的文件描述符—文件的操作句柄—通过这个fd指定要往哪个文件写入数据;
buf:要写入文件的数据的首地址;
count:要写入文件的数据长度;
返回值:成功返回实际写入文件的数据字节长度 失败返回:-1
sszie_t read(int fd,void *buf,szie_t count)
参数解释:
fd:open返回的文件描述符;
buf:一块缓冲区,从文件中读取的数据的放置位置,同时文件的当前读写位置向后移;count:想要读取的数据长度。
返回值:
(1)如果成功,返回读取的字节数;
(2)如果出错,返回-1并设置errno;
(3)如果在调read函数之前已是文件末尾,则返回0
off_t lseek(int fd,off_t offset,int whence)
参数解释:
fd:打开文件所返回的文件描述符;
offset:偏移量;
whence:偏移位置,从哪里开始偏移,有3种情况:
返回值:成功时返回当前位置相对于起始位置的偏移量;失败时返回-1
int close(int fd):
作用:通过文件描述符关闭文件,释放资源
fd:文件描述符
返回值:成功返回0,失败时返回-1
文件描述符:是一个非负整数,是操作文件的句柄。是内核中一个进程打开的文件描述信息表的下标–通过这个下标可以在内核中找到相应的文件描述信息,通过这个描述信息可以实现文件的操作。
为什么打开一个文件,如果不操作了一定要关闭,释放资源?
因为文件描述符实际是有限的,若不关闭文件,文件描述符用光,则在进程中就打不开新文件了.
一个程序运行起来,进程中会默认打开三个文件:
概念:将数据不再写入原本的文件,而是写入新的指定的文件中—实现方式就是替换这个描述符对应的文件描述信息,使文件描述符指向新的文件描述信息。
原理:实际是描述符的重定向,改变描述符所指向的文件,就改变了数据的流向
实现该功能的函数:int dup2(int oldfd,int newfd)
功能:让newfd这个描述符也指向odlfd所指向的文件,这时oldfd和newfd都能够操作oldfd所指向的文件。
文件描述符与文件流指针的关系:
文件描述符:非负整数—系统调用的IO接口
文件流指针:FILE结构体—typedef struct _IO_FILE FILE—库函数IO接口的操作句柄
问题来了:为什么多此一举封装fd?
请感受系统调用接口和库函数的区别:
那么问题又来了:缓冲区在什么地方?
在文件流指针的结构体中定义了缓冲区,这个缓冲区通常被称为用户态缓冲区
文件系统:就是磁盘上管理文件的系统
以linux下的ext2文件系统为例:
文件的存储流程:
通过超级块找到inode位图/数据块位图,通过数据块位图快速找到空闲的磁盘块存储文件数据,通过inode位图快速找到空闲的inode节点存储文件的元信息;—文件数据存储完毕。
获取文件的数据流程:
通过文件名打开一个文件,在所在目录文件中通过文件名找到这个文件的inode节点号;在磁盘超级块中找到inode节点区域,根据inode节点号,快速找到inode节点,得到数据存储的磁盘块号,取出数据。
每一个文件都有一个唯一的inode节点 ;
ls -i:可以看到文件的inode节点号;
软链接 / 硬连接:可以通过软链接文件或者硬链接文件操作源文件
如何创建软链接文件以及硬链接文件:(源文件:test.txt)
为源文件创建一个硬链接文件:ln test.txt test.hard
为源文件创建一个软链接文件:ln -s test.txt test.soft
软链接文件与硬链接文件的区别:
OK,今天笔者先总结到这里。如有问题或者疑惑,欢迎各位小伙伴们指出。我们一起交流,一起进步!