ftell/fseek在文件末尾附近失败

3

读取一个文本文件(该文件恰好是 PDS 成员 FB 80)

hFile = fopen(filename,"r");

并且已经到达文件中只剩下一行空行的地方。

FilePos = ftell(hFile);

然后阅读最后一行,该行仅包含一个 '\n' 字符。
fseek(hFile, FilePos, SEEK_SET);

导致失败:-

errno=(27) EDC5027I The position specified to fseek() was invalid.
fseek() 所指定的位置是前几行中由 ftell() 返回的值。 在我看到的具体错误情况下,其值为841。 通过调试器进行检查,这也是前面几行中由 ftell 返回的值。 它没有被破坏。
同一段代码在文件的其他位置运行正常,仅在记住位置时还剩一个空行需要读取时失败。
另一个SO上的答案简洁地概括了我的ftell/fseek的工作原理:
“从文本流返回的ftell值与您迄今读取的字符数之间没有可预测的关系。 您唯一可以依赖的是,您随后可以将其用作fseek或fseeko的偏移参数,以返回相同的文件位置。”
看起来我不能依赖我应该能够依赖的唯一一件事。
我的问题是,为什么fseek会以这种方式失败?

尝试使用 export _EDC_ZERO_RECLEN=Y - Milos Lalovic
有趣,我会试一下 - 只有一个 '\n' 被认为是零吗? - Morag Hughson
经过进一步思考,流是以文本模式还是二进制模式打开的? - meat
@meat - 如问题所述,这是一个文本文件,并且使用“r”打开。将更新问题文本以反映此情况。 - Morag Hughson
@MilosLalovic - 我终于尝试了你的建议,但是它并没有产生任何影响。 - Morag Hughson
2个回答

0

由于z/OS具有一些独特的文件格式,您可能会在知识中心文章中找到答案。

考虑到您正在处理PDS成员,我怀疑这是记录级I/O,它与分布式实现中更常见的流I/O处理方式不同。


POSIX文件函数支持以流模式从顺序源(在本例中为PDS成员)读取。 - meat
@Hogstrom - 请注意,我没有使用 type=record 的打开模式参数。因此,这不是记录级别的 I/O。PDS 成员只是一个小文本文件,固定块 80,没有什么复杂的。 - Morag Hughson

0

我不知道为什么fseek会以这种方式失败,但如果您的常见用法模式是使用ftell获取位置,然后使用fseek到该位置,我强烈建议改用fgetposfsetpos进行数据集I/O。不仅可以避免您发现的这个问题,而且对于某些数据集特征来说,性能也更好。


谢谢 - 实际上这是我现在所做的,但我也想彻底解决问题,因为这对我来说肯定不正确。 - Morag Hughson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接