为什么 POSIX API 没有文件结束函数?
在 POSIX API 中,read()
返回 0 表示已到达文件结尾。为什么没有一个单独的函数告诉您 read()
将返回零——而不需要您实际调用 read()
?
提问原因:由于您必须调用 read() 才能发现它会失败,这使得文件读取算法变得更加复杂,并且可能效率稍低,因为它们必须分配一个目标缓冲区,该缓冲区可能会失败。不需要。
我们可能想要做什么...
while ( !eof )
{
allocate buffer
read to buffer
process buffer
}
我们必须做什么...
while ( true )
{
allocate buffer
read to buffer
if ( eof ) release buffer, break;
process buffer
}
此外,这种行为似乎会传播到更高级别的 API,例如 fread()
和 feof( )
在 C 中——并且对如何正确使用 feof()
造成了很多混乱:
- C: 为什么“while (!feof (file))”总是错误?
- C++: < a href="https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong">为什么是 iostream::eof循环条件内被认为错误?
- Python:如何循环直到 EOF在Python 中?
In the POSIX API, read()
returns 0 to indicate that the end-of-file has been reached. Why isn't there a separate function that tells you that read()
would return zero -- without requiring you to actually call read()
?
Reason for asking: Since you have to call read()
in order to discover that it will fail, this makes file reading algorithms more complicated and maybe slightly less efficient since they have to allocate a target buffer that may not be needed.
What we might like to do...
while ( !eof )
{
allocate buffer
read to buffer
process buffer
}
What we have to do instead...
while ( true )
{
allocate buffer
read to buffer
if ( eof ) release buffer, break;
process buffer
}
Additionally, it seems like this behavior propagates itself into higher-level APIs such as fread()
and feof()
in C -- and creates a lot of confusion about how to use feof()
correctly:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要了解为什么会出现这种情况,请了解流结束本质上并不是永久性的情况。文件的读指针可能位于末尾,但如果随后通过写操作附加更多数据,则后续读取将会成功。
示例:在 Linux 中,从控制台读取时,后跟
^D
的新行将导致posix::read()
返回零(表示“文件结尾”) )。但是,如果程序没有终止,则程序可以继续读取(假设键入了其他行)。由于流结束不是永久情况,因此甚至没有 is_at_end() 函数(POSIX 没有)也许是有意义的。不幸的是,这确实给程序员(和/或包装器库)带来了一些额外的负担,以优雅且有效地处理这种复杂性。
To gain perspective on why this might be the case, understand that end-of-stream is not inherently a permanent situation. A file's read pointer could be at the end, but if more data is subsequently appended by a write operation, then subsequent reads will succeed.
Example: In Linux, when reading from the console, a new line followed by
^D
will causeposix::read()
to return zero (indicating "end of file"). However, if the program isn't terminated, the program can continue to read (assuming additional lines are typed).Since end-of-stream is not a permanent situation, perhaps it makes sense to not even have an is_at_end() function (POSIX does not). Unfortunately, this does put some additional burden on the programmer (and/or a wrapper library) to elegantly and efficiently deal with this complexity.