读取系统调用返回错误的字节数

时间:2019-05-30 08:40:43

标签: c++ linux system call stdio

我正在尝试使用读取系统调用来实现fread。我正在使用4264394字节的JPEG文件来测试我的代码。我正在使用用户缓冲区和文件类缓冲区。如果用户缓冲区大于类缓冲区,则数据将直接读入用户缓冲区。如果用户缓冲区小于文件类缓冲区,那么我首先将数据读取到文件缓冲区中,一旦数据被填充,我将其复制到用户缓冲区中并从文件中重新读取。

我的问题是,如果尝试通过将文件类缓冲区设置为小于用户缓冲区的值来直接读取JPEG文件,则会将文件直接读取到用户缓冲区中,并且大小正确为4264394字节。但是,如果我尝试通过将文件类缓冲区设置为大于用户缓冲区的值来使用它,则会出现一些奇怪的行为,并且读取似乎会误读文件大小。我正在使用8192字节的文件类缓冲区和1024的用户缓冲区,因此文件类缓冲区恰好是用户缓冲区的8倍。

size_t File::fread(void *ptr, size_t size, size_t nmemb) {

    off_t lseekk=0;
    lseekk = lseek(this->fd_, 0 , SEEK_CUR);
    cout << "lseek at begining is " << lseekk << endl;

    size_t bytes_read = 0;
    char* pChar;
    pChar = (char *) ptr;

    cout << "fread started" << endl;
    int flush;

    if (this->buf_state == WRITING) {
        flush = this->fflush(); // make sure to empty the buffer before starting to read
        if (flush == 0) {
            cout << "Flush successful" << endl;
        } else {
            cout << "Nothing to flush" << endl;
        }
    }

    this->buf_state = READING;

    if (nmemb < (size_t) bufsiz) {
        if (cur_buf_size == 0) {
            cout << "No data buffered" << endl;

            lseekk = lseek(this->fd_, 0 , SEEK_CUR);
            cout << "lseek before read is " << lseekk << endl;
            cur_buf_size = read(this->fd_, this->buf, this->bufsiz);

            lseekk = lseek(this->fd_, 0 , SEEK_CUR);
            cout << "lseek after read is " << lseekk << endl;

            if ((size_t)cur_buf_size < nmemb) { // in case no data buffered and the total size of file is less than nmemb
                nmemb = cur_buf_size;
            }


            if (cur_buf_size < 0) {
                perror("Error Reading File");
                exit(1);
            } else {
                cout << "file reading successful, number of bytes read is: " << cur_buf_size << endl;

                for (size_t i = 0; i < nmemb; i++) {
                    //char c;
                    char c = (char) buf[i];
                    pChar[i] = c;
                }
                buf = buf + nmemb;
                cur_buf_size = cur_buf_size - nmemb;


                return nmemb;
            }

        } else if ((cur_buf_size > 0) && (nmemb <= (size_t)cur_buf_size)) {
            cout << "enough data buffered, will not call read" << endl;
            for (unsigned i = 0; i < nmemb; i++) {
                char c = (char) buf[i];
                pChar[i] = c;
            }
            buf = buf + nmemb;
            cur_buf_size = cur_buf_size - nmemb;
            return nmemb;

        } else if (cur_buf_size > 0 && nmemb > (size_t)cur_buf_size) {
            int nmemb2 = nmemb;

            cout << "not enough data buffered, will call read to re-fill buffer" << endl;
            int remaining = cur_buf_size;

            buf = buf + remaining; // moving buffuer forward to start reading after the remianing chars

            cur_buf_size = read(this->fd_, this->buf, (this->bufsiz - remaining));
            if (cur_buf_size == -1){
              return remaining;
            }

            cur_buf_size = cur_buf_size + remaining;

            buf = buf - remaining; // reverting buffer again to where it was
            if ((size_t)cur_buf_size < nmemb) {
                nmemb2 = cur_buf_size;
                for (size_t i = 0; i < nmemb; i++) {
                    char c = (char) buf[i];
                    if (c == ' ') {
                        pChar[i] = ' ';
                    } else {
                        pChar[i] = c;
                    }
                }
                buf = buf + nmemb;
                cur_buf_size = cur_buf_size - nmemb;
                return nmemb2;
            }

            cout << "cur_buf_size is " << cur_buf_size << endl;
            for (size_t i = 0; i < nmemb; i++) {
                char c = (char) buf[i];
                if (c == ' ') {
                    pChar[i] = ' ';
                } else {
                    pChar[i] = c;
                }
            }
            buf = buf + nmemb;
            cur_buf_size = cur_buf_size - nmemb;
            return nmemb2;
        }
    } else {
        cout << "no double buffering, reading/writing data directly to/from the source/destination." << endl;
        bytes_read = read(this->fd_, ptr, nmemb);
        if (bytes_read < 0) {
            perror("Error Reading File");
            exit(1);
        }
        return bytes_read;
    }
    return bytes_read;
}

这是我打开文件并阅读文件的主要部分:

total_bytes_read = 0;
int chunk_size4 = 1024;
const char *name4 = "20190211_070835.jpg";
const char * mode4 = "r";
File * f4 = new File(name4, mode4);
char *ubuf4 = new char[chunk_size4];

while (true) {
bytes = f4->fread(ubuf4, 1, chunk_size4);
cout << bytes << endl;
if (bytes < 0) {
    perror("Error Reading File");
    exit(1);
}
if (bytes == 0) {
    cout << "Total Bytes Read is: " << total_bytes_read << endl;
    total_bytes_read=0;
    break;
} else {
    for (int i = 0; i < chunk_size; i++) {
        //cout << ubuf[i];
    }
    //cout << endl;
}
total_bytes_read = total_bytes_read + bytes;
}

以下是输出:

 File opened r, File Descriptor is 6
 lseek at begining is 0
 fread started
 No data buffered
 lseek before read is 0
 lseek after read is 8192
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 8192
 fread started
 No data buffered
 lseek before read is 8192
 lseek after read is 16384
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 16384
 fread started
 No data buffered
 lseek before read is 16384
 lseek after read is 24576
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 24576
 fread started
 No data buffered
 lseek before read is 24576
 lseek after read is 32768
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 32768
 fread started
 No data buffered
 lseek before read is 32768
 lseek after read is 40960
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 40960
 fread started
 No data buffered
 lseek before read is 40960
 lseek after read is 49152
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 49152
 fread started
 No data buffered
 lseek before read is 49152
 lseek after read is 57344
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 57344
 fread started
 No data buffered
 lseek before read is 57344
 lseek after read is 65536
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 65536
 fread started
 No data buffered
 lseek before read is 65536
 lseek after read is 73728
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 73728
 fread started
 No data buffered
 lseek before read is 73728
 lseek after read is 81920
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 81920
 fread started
 No data buffered
 lseek before read is 81920
 lseek after read is 90112
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 90112
 fread started
 No data buffered
 lseek before read is 90112
 lseek after read is 98304
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 98304
 fread started
 No data buffered
 lseek before read is 98304
 lseek after read is 106496
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 106496
 fread started
 No data buffered
 lseek before read is 106496
 lseek after read is 114688
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 114688
 fread started
 No data buffered
 lseek before read is 114688
 lseek after read is 122880
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 122880
 fread started
 No data buffered
 lseek before read is 122880
 lseek after read is 131072
 file reading successful, number of bytes read is: 8192
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 131072
 fread started
 No data buffered
 lseek before read is 131072
 lseek after read is 134048
 file reading successful, number of bytes read is: 2976
 1024
 lseek at begining is 134048
 fread started
 enough data buffered, will not call read
 1024
 lseek at begining is 134048
 fread started
 not enough data buffered, will call read to re-fill buffer
 928
 lseek at begining is 134048
 fread started
 0
 Total Bytes Read is: 134048

输出表明,通过每次从文件中读取8192个字节,然后以8个1024块的形式将这些字节传递到用户缓冲区,然后再次读取,该读取工作正常。一方面,它决定只读取一小块,然后读取EOF

我试图在另一台Linux机器上运行代码,但读取的字节数却不同。知道有什么问题吗?是我的代码或读取系统调用异常吗?

最后,我在文件的开头使用lseek进行了检查,lseek(this->fd_, 0 , SEEK_END)返回4264394字节,这意味着操作系统可以看到文件为4264394字节。

想知道可能是什么问题?

0 个答案:

没有答案
相关问题