c_cpp“linux的环境高级编程”作业2(代码片段)

author author     2023-01-10     274

关键词:

#include <fcntl.h>
#include <unistd.h>
#include <cstdarg>
#include <cstring>
#include <iostream>

using namespace std;

class FileOperator
    //申请固定大小的读缓存和写缓存
    static const int READ_BUF_LEN = 4 * 1024;
    static const int WRITE_BUF_LEN = 4 * 1024;
    unsigned char readBuf[READ_BUF_LEN];
    unsigned char writeBuf[WRITE_BUF_LEN];
    //分别记录读缓存和写缓存对应文件中内容的起始偏移量和终止偏移量
    long startPositionOfReadBuf = -1;
    long startPositionOfWriteBuf = -1;
    long endPositionOfReadBuf = -1;
    long endPositionOfWriteBuf = -1;
    //记录打开文件的标识符
    int filePointer;
public:
    //打开文件并保存文件标识
    int fopen(const char *filePath, int oflag, ...)
        int filePointer;
        if((oflag == O_CREAT|O_WRONLY)||(oflag == O_CREAT|O_RDONLY)||(oflag == O_CREAT|O_RDWR))
            va_list pvar;
            va_start(pvar, oflag);
            filePointer = open(filePath, oflag, va_arg(pvar, int));
            va_end(pvar);
        
        else
            filePointer = open(filePath, oflag);
        
        this->filePointer = filePointer;
        return filePointer;
    
    //在文件的当前偏移量处读取数据
    ssize_t fread(void *buf, size_t len)
        //如果写缓存有数据,就刷新到磁盘,重置写缓存
        if(endPositionOfWriteBuf > startPositionOfWriteBuf)
            long writeNum = write(filePointer, writeBuf, (size_t) (endPositionOfWriteBuf - startPositionOfWriteBuf));
            if(writeNum == -1) 
                return -1;
            
            startPositionOfWriteBuf = -1;
            endPositionOfWriteBuf = -1;
        
        //如果要读取的数据都在读缓存中,就直接返回数据
        long readStart = lseek(filePointer, 0, SEEK_CUR);
        if((readStart >= startPositionOfReadBuf)&&((long)(readStart + len) <= endPositionOfReadBuf))
            memcpy(buf, &readBuf[readStart - startPositionOfReadBuf], len);
            return len;
        
        else 
            //从磁盘上的文件读取数据并进行缓存
            unsigned long alreadyReadNum = 0;
            unsigned long toReadNum = len;
            //一次读取的数据可能超过缓存大小,这时缓存的数据是要读取数据的最后一块不超过缓存大小的数据
            while (toReadNum > 0) 
                startPositionOfReadBuf = lseek(filePointer, 0, SEEK_CUR);
                long readNum = read(filePointer, readBuf, (size_t) READ_BUF_LEN);
                endPositionOfReadBuf = startPositionOfReadBuf + readNum;
                if (readNum == -1) 
                    return -1;
                 else if (readNum == 0) 
                    break;
                 else 
                    unsigned long realReadNum = toReadNum < readNum ? toReadNum : (unsigned long) readNum;
                    memcpy(buf + alreadyReadNum, readBuf, (size_t) realReadNum);
                    toReadNum -= realReadNum;
                    alreadyReadNum += realReadNum;
                
            
            return alreadyReadNum;
        
    
    //在文件的当前偏移量处写入数据
    ssize_t fwrite(void *buf, size_t len)
        long writeStart = lseek(filePointer, 0, SEEK_CUR);
        //如果写入位置与读缓存有重合,则同时要修改读缓存内容
        if((writeStart < endPositionOfReadBuf)&&(writeStart + len > startPositionOfReadBuf))
            long startPosition = writeStart > startPositionOfReadBuf ? writeStart : startPositionOfReadBuf;
            long endPosition = (writeStart + (long)len < endPositionOfReadBuf)?(writeStart + (long)len):endPositionOfReadBuf;
            memcpy(readBuf + startPosition - startPositionOfReadBuf, buf + startPosition - writeStart,
                   (size_t) (endPosition - startPosition));
        
        //如果要写入数据对应的位置包含在已有写缓存中,则直接对写缓存进行修改
        if((writeStart >= startPositionOfWriteBuf)&&((long)(writeStart + len) <= endPositionOfWriteBuf))
            memcpy(&writeBuf[writeStart - startPositionOfWriteBuf], buf, len);
            return len;
        
        else 
            //否则将原有缓存数据刷新到磁盘,然后写缓存保存新数据
            unsigned long alreadyWrittenNum = 0;
            unsigned long toWriteNum = len;
            while (toWriteNum > 0) 
                long writeNum = write(filePointer, writeBuf, (size_t) (endPositionOfWriteBuf - startPositionOfWriteBuf));
                if(writeNum == -1) 
                    return -1;
                
                unsigned long realWriteNum = toWriteNum < WRITE_BUF_LEN ? toWriteNum : (unsigned long) WRITE_BUF_LEN;
                memcpy(writeBuf, buf + alreadyWrittenNum, (size_t) realWriteNum);
                startPositionOfWriteBuf = lseek(filePointer, 0, SEEK_CUR);
                endPositionOfWriteBuf = startPositionOfWriteBuf + realWriteNum;
                toWriteNum -= realWriteNum;
                alreadyWrittenNum += realWriteNum;
            
            return alreadyWrittenNum;
        
    
    //修改当前文件偏移量
    __off_t fseek(__off_t offset, int whence)
        //修改之前将写缓存刷新到磁盘并重置
        long writeNum = write(filePointer, writeBuf, (size_t) (endPositionOfWriteBuf - startPositionOfWriteBuf));
        if(writeNum == -1) 
            return -1;
        
        startPositionOfWriteBuf = -1;
        endPositionOfWriteBuf = -1;
        return lseek(filePointer, offset, whence);
    
    //关闭文件
    int fclose()
        //关闭之前要先将写缓存刷新到磁盘,然后重置读写缓存
        long writeNum = write(filePointer, writeBuf, (size_t) (endPositionOfWriteBuf - startPositionOfWriteBuf));
        if(writeNum == -1) 
            return -1;
        
        startPositionOfReadBuf = -1;
        startPositionOfWriteBuf = -1;
        endPositionOfReadBuf = -1;
        endPositionOfWriteBuf = -1;
        return close(filePointer);
    
;
int main() 
    char writeBuf[1000] = "234v4wqrtmq24n";
    char readBuf[1000] = '\0';
    FileOperator* fileOperator = new FileOperator();
    int filePointer = fileOperator->fopen("/home/developerdong/task1.txt", O_RDWR);
    cout << fileOperator->fwrite(writeBuf, strlen(writeBuf)) << endl;

    fileOperator->fread(readBuf, 11);
    cout << readBuf << endl;

    fileOperator->fseek(0, SEEK_SET);
    fileOperator->fread(readBuf, 11);
    cout << readBuf << endl;
    fileOperator->fclose();
    delete(fileOperator);

c_cpp“linux的环境高级编程”作业1(代码片段)

查看详情

c_cpp给定Ñ个作业的集合j1,j2,......,jn。每个作业必须先由机器1处理,然后由机器2处理。作业籍需要机器ĵ的处理时间为tji。对于一个确定的作业调度,设fji是作业我在(代码

查看详情

c_cpp给定Ñ个作业的集合j1,j2,......,jn。每个作业必须先由机器1处理,然后由机器2处理。作业籍需要机器ĵ的处理时间为tji。对于一个确定的作业调度,设fji是作业我在(代码

查看详情

c_cpp【分支限界法】批处理作业调度(代码片段)

查看详情

c_cpp【动态规划】流水作业调度【3.9】(代码片段)

查看详情

c_cpp【回溯法】批处理作业调度【5.3】(代码片段)

查看详情

c_cppÑ个作业1,2,...,n要在由2台机器m1和m2组成的流水线上完成加工。每个作业加工的顺序都是先在m1上加工,然后在m2上加工.m1和m2加工作业我所需的时间分别为ai和璧(代码

查看详情

c_cpp第1周为c程序员编写的c++作业(代码片段)

查看详情

c_cpp条件2(代码片段)

查看详情

c_cpp2.cpp(代码片段)

查看详情

c_cpp【2】图像显示(代码片段)

查看详情

c_cpp199-2.cpp(代码片段)

查看详情

c_cpp测试2.cpp(代码片段)

查看详情

c_cpp345-2.cpp(代码片段)

查看详情

c_cpp实验2(avrc)(代码片段)

查看详情

c_cpp2.添加两个数字(代码片段)

查看详情

c_cpp添加2个大号(代码片段)

查看详情

c_cpp实验室2电位(代码片段)

查看详情