交替使用 FILE 指针和文件描述符
interchangeably using FILE pointer and file descriptor
当我在 fileno()
给出的文件描述符上调用较低级别的函数 API 时,如 read/write,我如何确保 FILE*
文件描述符状态保持同步函数而不是调用 fread
/fwrite
。
我想到的场景是:
fp = fopen(...)
fd = fileno(fp)
read(...,fd)
在上述 read(...,fd)
之后,我希望 fp
(FILE*
) 在读取字节后正确定位。 ftell
和 feof
应该仍然指向正确的信息。
这个问题比你想象的要复杂:
基于 FILE*
的 API(例如 fread()
)使用内部缓冲区,并且根据您使用的 C 库(版本),您必须考虑...
...fopen()
可能已经将字节读入缓冲区,所以fp
的文件指针是0,但是fd
的文件指针是不是 0.
这意味着在使用fd
之前,您必须确保fd
与fp
同步。
...C 库可能假定 fd
的文件指针仅由基于 FILE
的调用修改。
这意味着你必须在使用read()
和调用任何基于FILE
的函数之间恢复fd
的文件指针。
因此以下代码可能有效:
fp = fopen(...)
fd = fileno(fp)
/* Remember file position of fd */
oldpos = lseek(fd, 0, SEEK_CUR);
/* Ensure file position of fd is in sync with fp */
lseek(fd, ftell(fp), SEEK_SET);
read(...,fd)
/* Get new file position of fd */
newpos = lseek(fd, 0, SEEK_CUR);
/* Restore old file position of fd */
lseek(fd, oldpos, SEEK_SET);
/* Keep fp in sync with fd */
fseek(fp, newpos, SEEK_SET);
(但是,不能保证此代码适用于每个存在的 C 库。)
当我在 fileno()
给出的文件描述符上调用较低级别的函数 API 时,如 read/write,我如何确保 FILE*
文件描述符状态保持同步函数而不是调用 fread
/fwrite
。
我想到的场景是:
fp = fopen(...)
fd = fileno(fp)
read(...,fd)
在上述 read(...,fd)
之后,我希望 fp
(FILE*
) 在读取字节后正确定位。 ftell
和 feof
应该仍然指向正确的信息。
这个问题比你想象的要复杂:
基于 FILE*
的 API(例如 fread()
)使用内部缓冲区,并且根据您使用的 C 库(版本),您必须考虑...
...
fopen()
可能已经将字节读入缓冲区,所以fp
的文件指针是0,但是fd
的文件指针是不是 0.这意味着在使用
fd
之前,您必须确保fd
与fp
同步。...C 库可能假定
fd
的文件指针仅由基于FILE
的调用修改。这意味着你必须在使用
read()
和调用任何基于FILE
的函数之间恢复fd
的文件指针。
因此以下代码可能有效:
fp = fopen(...)
fd = fileno(fp)
/* Remember file position of fd */
oldpos = lseek(fd, 0, SEEK_CUR);
/* Ensure file position of fd is in sync with fp */
lseek(fd, ftell(fp), SEEK_SET);
read(...,fd)
/* Get new file position of fd */
newpos = lseek(fd, 0, SEEK_CUR);
/* Restore old file position of fd */
lseek(fd, oldpos, SEEK_SET);
/* Keep fp in sync with fd */
fseek(fp, newpos, SEEK_SET);
(但是,不能保证此代码适用于每个存在的 C 库。)