linux文件读写(二)
1.文件描述符是什么?
文件描述符:它其实是一个数字,这个数字在一个进程中表示一个特定的含义,当我们open打开一个文件时,操作系统在内存中构建了一些数据结构来表示这个动态文件,然后返回给应用程序一个数字作为文件描述符,这个数字就和我们内存中维护这个动态文件的这些数据结构挂钩绑定上了。以后我们应用程序如果要操作这一个动态文件,只需要用这个文件描述符进行区分。简单来说,它是来区分多个文件的(在打开多个文件的时候)。
文件描述的作用域就是当前的进程,出了这个当前进程,这个文件描述符就没有意义了。
2.文件的定义
文件平时是存储在块设备的文件系统中,称为静态文件。
当我们打开文件进行操作时,linux的内核操作:在进程中创建一个打开文件的数据结构来存储信息(记录打开的文件),并且内核在内存中申请一段内存,并将块设备中的文件读取到内存的特定地址来进行管理存放(动态文件)。
当我们对动态文件读写时,此时动态文件与静态文件的内容不同步。
当我们close(关闭)动态文件时,此时内核中的动态文件会更新(同步)块设备中的静态文件。
为什么这样设计?
块设备的本身读写不灵活,是按块操作的,而内存中则是按字节单位操作,可以随机操作灵活。
3.函数(lseek)
函数原型
#include<unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数
fd: 文件描述符
offset: 偏移量
whence:位置
如果whence=SEEK_SET,则偏移量设置为文件开始处offset字节。
如果whence=SEEK_CUR,则偏移量设置为文件当前位置加offset字节,offset可正可负。
如果whence=SEEK_END,则偏移量为文件结束位置加offset字节,offset可正可负。
返回值
如果返回-1则失败,返回成功则为当前文件的偏移量。
lseek的使用
文件指针移动到头部
lseek(fd,0,SEEK_SET);
文件指针在当前位置
int len=lseek(fd,0,SEEK_CUR);
获取文件的大小
int len=lseek(fd,0,SEEK_END);
测试代码
#include<stdio.h>
#include<error.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main(int args,char *argv[])
{
int fd;
int len;
int n_read;
int n_write;
char *str="write successful";
char readbuf[128];
memset(readbuf,0,sizeof(readbuf)/sizeof(char));
if((fd=open("./test",O_RDWR||O_CREAT))==-1)
{
perror("open");
exit(-1);
}
len=lseek(fd,0,SEEK_END);
printf("get size=%d",len);
if((n_write=write(fd,str,strlen(str)))==-1)
{
perror("write");
exit(-1);
}
lseek(fd,0,SEEK_SET);
if((n_read=read(fd,readbuf,sizeof(readbuf)))==-1)
{
perror("read");
exit(-1);
}
printf("read file : %s",readbuf);
close(fd);
return 0;
}
测试结果:(运行了两次,原文件内容接上篇)