本文浅浅的描述一下linux文件io基本的函数,文件IO也称为系统调用IO,是操作系统为"用户态"运行的进程和硬件交互提供的一组接口,即操作系统内核留给用户程序的一个接口,按照操作系统的结构划分,Linux系统自上而下依次是:用户进程、Linux内核、物理硬件。其中Linux内核包括系统调用接口和内核子系统两部分。Linux内核处于“承上启下”的关键位置,向下管理物理硬件,向上为操作系统和应用程序提供接口,这里的接口就是系统调用。
下面介绍一下一般文件的操作open、read、write、lseek、close函数。
open
头文件
#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 文件不存在创建(需要open传入第三个参数)
O_TRUNC 文件存在截断成0(清0)
O_APPEND 追加打开
O_ASYNC 异步IO
O_NONBLOCK 非阻塞IO
O_EXCL 检测文件是否存在
返回值
成功返回新文件描述符
失败返回-1
close
头文件
#include <unistd.h>
函数
int close(int fd);
功能
关闭文件描述符
参数
文件描述符
返回值
成功返回0
失败返回-1
write
头文件
#include <unistd.h>
函数
ssize_t write(int fd, const void *buf, size_t count);
功能
向文件描述符对应文件中写入buf开始的count个字节数据
参数
fd:文件描述符
buf:存放数据空间的首地址
count:写入字节的个数
返回值
成功返回实际写入的字节数
失败返回-1
read
头文件
#include <unistd.h>
函数
ssize_t read(int fd, void *buf, size_t count);
功能
从文件描述符中读取count个字节,放入buf指向的空间中
参数
fd:文件描述符
buf:存放数据空间首地址
count:最多读取数据字节数
返回值
成功返回实际读到字节数
失败返回-1
读到文件末尾返回0
现在我用以上介绍的四个函数接口来实现一个文件的拷贝
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd_src = 0;
int fd_dst = 0;
char tmpbuff[1024] = {0};
ssize_t nret = 0;
fd_src = open("src.jpg",O_RDONLY);//打开文件只读
fd_dst = open("dst.jpg",O_WRONLY | O_TRUNC | O_CREAT,0664);/*打开文件读写、截断为0、如果文件不存在则创建 mode(110 110 100)*/
if(-1 == fd_dst || -1 == fd_src)
{
perror("fail to open");
return -1;
}
while (1)
{
nret = read(fd_src, tmpbuff, sizeof(tmpbuff));//读到多少返回到nret
if(0 >= nret)//如果nret不大于0则说明读到末尾
{
break;
}
write(fd_dst,tmpbuff,nret);//上面nret为多少就写多少
}
close(fd_src);
close(fd_dst);//关闭两文件
return 0;
}
lseek
头文件
#include <unistd.h>
函数
off_t lseek(int fd, off_t offset, int whence);
功能
重定位文件描述符的偏移量
参数
fd:文件描述符
offset:偏移量
>0 向后偏移
<0 向前偏移
whence:
SEEK_SET 文件开头
SEEK_CUR 文件当前位置
SEEK_END 文件末尾
返回值
成功返回偏移量
失败返回-1
下面是运用lseek函数对文件进行操作
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
off_t len = 0;
fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (-1 == fd)
{
perror("fail to open");
return -1;
}
len = lseek(fd, 10, SEEK_SET);//定位文件开头向后偏移10
printf("偏移量:%ld\n", len);
write(fd, "a", 1);
len = lseek(fd, -5, SEEK_CUR);//定位文件当前向前偏移5
printf("偏移量:%ld\n", len);
write(fd, "b", 1);
len = lseek(fd, 0, SEEK_SET);//定位文件开头无偏移
printf("偏移量:%ld\n", len);
write(fd, "c", 1);
close(fd);
return 0;
}
可以看出来 ,起初定位到10偏移量为10,插入一个a后偏移就为11,从当前向左偏移5个后,打印出偏移量为6,最后从开头0偏移所以偏移量为0.
打开创建后的文件内部插入结果如图(红色部分无字符也不为空格 \0 \n,所以无法正常显示)