追加写入
open(pathname, O_WRONLY | O_CREAT |"O_APPEND"//这个是追加写入的标识符,和截断正好作用相反
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
计算字节数
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[] )
{
int fd = -1;
fd = open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
return -1;
}
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
//第二哥参数:相对参照位置的偏移量,当为正数是,向右偏移
//第三个参数:参照位置,一般有三个SEEK_SET,SEEK_CUR,SEEK_END.
if(-1 == offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);//这个位置是ld,长整形
}
return 0;
}
lseek 的一些基本知识
int main(int argc,char *argv[] )
{
int fd = -1;
fd = open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
//里面第一个参数,是运行文件后面跟着的第一个文件的地址
if(-1 == fd)
{
return -1;
}
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1 == offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
offset = lseek(fd,10,SEEK_SET);
printf("offset = %ld\n",offset);
char *pData = "888";
write(fd,pData,strlen(pData));
//写入数据,是把原先位置的内容覆盖掉了
lseek(fd,5,SEEK_CUR);
write(fd,"666",3);
//他的意思是在当前位置向后5个位置,写入666
//当成功读写n个字节时,读写位置会从没有发生读写前的位置往后偏移n个字节
//每次读写文件是,都是从当前的读写位置开始读写。
close(fd);
return 0;
}
读取指定位置结构体
typedef struct student
{
char name[20];
int num;
char sex[10];
int score;
}student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
student stu;
memset(&stu,'\0',sizeof(student));//初始话里面的内容
read(fd, &stu, sizeof(student));
printf("name:%s,num:%d,sex:%s,score:%d\n",
stu.name,stu.num,stu.sex,stu.score);
off_t offset = lseek(fd,sizeof(student),SEEK_CUR);
read(fd, &stu, sizeof(student));
printf("name:%s,num:%d,sex:%s,score:%d\n",
stu.name,stu.num,stu.sex,stu.score);
offset = lseek(fd,2*sizeof(student),SEEK_CUR);
read(fd, &stu, sizeof(student));
printf("name:%s,num:%d,sex:%s,score:%d\n",
stu.name,stu.num,stu.sex,stu.score);
close(fd);
}
return 0;
}
pread和pwrite
/写入数据,是把原先位置的内容覆盖掉了
//当一个程序存在多个运行分支,并且每个运行分支都有可能操作文件时
// 存在以下问题:
// 当A分支使用lseek设置读写位置完成时,A分支的运行暂停,B分支开始运行,
//并且B分支对同一个文件进行了读写操作,从而改变了A分支设置的读写位置。
//当B分支运行暂停,A分支重新接着往后运行时,若A分支要对文件进行读写,
//那么读写位置并不是之前设置的位置,而是B分支运行后的读写位置。
//从而得不到预期的结果。
//问题解决方案:
//将A分支的lseek和之后的读写操作合成原子操作。操作不可分,要么都执行,要么不执行。
// 1,将操作部分使用锁锁住,合成原子操作。
// 2,调用pread()或者pwrite()函数完成操作
#if 0
lseek(fd,5,SEEK_CUR);
write(fd,"666",3);
#endif
pData = "hate";
ssize_t size = pwrite(fd,pData,strlen(pData),5);
//这里面的5,只能是从文件头开始第五个
if(-1 == size)
{
printf("pwrite error:%s\n",strerror(errno));
}
close(fd);