目录
一、文件IO相关概念
1.1 文件IO与标准IO的区别
1.文件IO遵循POSIX标准,文件IO实际上使用系统调用函数;
2.标准IO适用于操作普通文件,文件IO适用于任意类型文件;3.标准IO中通过流唯一标识一个文件,文件IO中通过文件描述符唯一标识一个文件 ;
1.2 文件描述符
对于内核而言,所有打开文件都由文件描述符引用。
文件描述符是一个按顺序分配的最小的非负整数,当用户打开或者新建一个文件时,系统会向当前进程返回一个最小的可用的文件描述符。
三个特殊的文件描述符(默认打开) :
标准输入--0--stdin
标准输出--1--stdout
标准错误--2--stderr
二、文件相关系统调用函数
2.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 : 打开文件的方式
O_RDONLY : 以只读方式打开文件
O_WRONLY : 以只写方式打开文件
O_RDWR : 以读写方式打开文件
前三个选项必须选择一个进行填写
O_CREAT : 当打开文件不存在时,用该选项创建新文件,并用第三个参数为其设置权限;如果文件存在,加不加该参数都可以,不会对其有影响
O_EXCL : 一般和O_CREAT联合使用,用于检测文件是否存在
O_APPEND : 以追加的方式打开文件,在文件末尾另起一行继续写入
O_TRUNC : 打开文件之后,会将原文件清空
mode :
当需要创建新的文件时,需要用该参数给新建文件设置初始权限,一般设为0664(普通文件权限)返回值 :
成功返回文件描述符,失败返回-1
代码实现
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt", O_RDONLY | O_CREAT | O_EXCL, 0664);//打开文件,如果文件不存在就创建,并设置文件初始权限为0664
if(fd < 0)
{
perror("open");
return -1;
}
printf("open successful!\n");
return 0;
}
2.2 关闭文件 --- close
#include <unistd.h>
int close(int fd);
参数 :
fd : 要关闭的文件描述符
返回值 :
成功返回0,失败返回-1
2.3 读写文件
2.3.1 读文件 --- read
函数原型
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数 :
fd : 读取文件的文件描述符
buf : 用户自定义的缓冲区,用于存放读取的内容
count : 请求读取的字节数
返回值 :返回值如果成功返回读到的字节数,失败返回-1,返回0表示读到文件末尾
示例:从1.txt 文件中读取5个字节并打印到终端
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("1.txt", O_RDONLY);
if(fd < 0)
{
perror("open");
return -1;
}
char buf[64] = {0};
int ret = read(fd, buf, 5);//从1.txt文件中读,存在buf中,读取5个字节
if(ret < 0)
{
perror("read");
return -1;
}
printf("read %d bytes:%s", ret, buf);
return 0;
}
2.3.2 写文件 --- write
函数原型
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数 :
fd : 读取文件的文件描述符
buf : 用户自定义的缓冲区,用于存放准备写入的内容
count : 请求写入的字节数
返回值 :
返回值如果成功返回读到的字节数,失败返回-1
write()出错的常见原因 : 磁盘已满或者超过了一个给定进程的文件长度限制
示例:从键盘输入字符,写入1.txt 文件中
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd = open("1.txt", O_WRONLY | O_CREAT, 0664);//要写入文件,则文件必须存在,不存在就创建文件
if(fd < 0)
{
perror("open");
return -1;
}
char buf[64] = {0};
fgets(buf, 64, stdin);//从键盘写入数据
//buf[strlen(buf)-1] = '\0';//处理换行符
int ret = write(fd, buf, strlen(buf));//从键盘写入strlen(buf)个字符,存入1.txt文件中
if(ret < 0)
{
perror("write");
return -1;
}
return 0;
}
2.4 文件定位 --- lseek
函数原型
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数 :
fd : 文件描述符
offset : 偏移量,可正可负;正:往后偏移,负:往前偏移
whence : 基准点
SEEK_SET : 定位在文件开头
SEEK_CUR : 定位在文件当前位置
SEEK_END : 定位在文件末尾
返回值:成功返回当前定位位置相对于文件开头的偏移量,失败返回-1
示例:打开文件,往后偏移4个字节,并将此时指向的字节打印到终端;输出该文件的大小
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("1.txt", O_RDONLY);
int ret = lseek(fd, 4, SEEK_SET);//往后偏移4个字节
printf("ret = %d\n", ret);//打印偏移量
char buf[64] = {0};
read(fd, buf, 1);//从文件中读1个字节
printf("%s\n", buf);
ret = lseek(fd, 0, SEEK_END);//定位在文件末尾,打印出来的值相当于该文件大小
printf("file_size = %d\n", ret);
return 0;
}