系统 第二天 :读写

追加写入

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);

你可能感兴趣的:(系统 第二天 :读写)