жучара писал(а): ↑23.09.2022 19:27
я не понимаю, почему lseek должен куда-то уезжать. Ещё и конечно же. Он должен установить счётчик байтов куда велено и вернуть смещение и никуда не уезжать. А если уезжает- грош цена такой функции. Установил смещение, а на самом деле оно другое- и другое и возвращает. Мда.
Функции, работающие с указателями FILE*, реализованы поверх функций, работающих с файловыми дескрипторами (int fd), но при этом полагаются на то, что напрямую файловым дескриптором вы пользоваться не будете. Например, fread() читает более крупные порции, чем вы запрашиваете, и вместо возвращения помещает лишние данные в буфер, чтобы следующий вызов fread() мог просто взять их из буфера.
Функция fseek() гарантирует, что функции, работающие с FILE*, вернут данные, расположенные в запрошенном месте, но с файловым дескриптором может сделать всё, что ей угодно (лишь бы это не помешало дальнейшему использованию этого FILE*). В данном случае, судя по всему, она решила сэкономить системный вызов, предположив, что вы после неё вызовете fread(). Она могла бы вызвать lseek() и позволить последующему fread() вызвать read(), но это было бы целых два системных вызова. Вместо этого она, судя по всему, вызвала read() и поместила результат в буфер, чтобы та позиция, на которую вы хотели переместиться, оказалась внутри буфера (а позиция файлового дескриптора сдвинулась в положение сразу после буфера). В этом случае последующий fread() не будет использовать системных вызовов, а просто вернёт данные из буфера.
Используйте либо FILE*, либо fd, но не и то, и другое.