Я пытаюсь реализовать fread
, используя системный вызов read.Я использую файл JPEG, который составляет 4264394 байта, чтобы проверить мой код.Я использую пользовательский буфер и буфер класса файлов.Если пользовательский буфер больше буфера класса, то данные считываются непосредственно в пользовательский буфер.если пользовательский буфер меньше буфера класса файлов, то я сначала читаю данные в буфер файлов, как только он заполняется, я копирую их в буфер пользователя и перечитываю из файла.
Моя проблема заключается в том, что если я пытаюсь прочитать файл 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 байта.
Хотите знать, что может быть не так?