【问题标题】:Problem with fseekfseek 的问题
【发布时间】:2011-02-17 10:56:29
【问题描述】:

这是我的代码。

if(fseek(file,position,SEEK_SET)!=0)
{
  throw std::runtime_error("can't seek to specified position");
}

我曾经假设即使position 大于文件中的字符数,此代码也可以正常工作(即抛出错误),但事实并非如此。所以我想知道在试图寻找文件范围之外时如何处理寻找失败?

【问题讨论】:

    标签: c++ c file fseek


    【解决方案1】:

    好吧,在执行fseek 之前,您始终可以检查文件长度。

    void safe_seek(FILE* f, off_t offset) {
        fseek(f, 0, SEEK_END);
        off_t file_length = ftell(f);
        if (file_length < offset) {
            // throw!
        }
        fseek(f, offset, SEEK_SET);
    }
    

    请注意,这不是线程安全的。

    【讨论】:

    • 或者使用 fstat 代替 fseek。这消除了恢复当前搜索位置的需要。
    • 是的,但我认为 fstat 不能保证在非 Unix 系统上可用。
    • fstat 应该在任何符合 POSIX 的系统上可用:pubs.opengroup.org/onlinepubs/009695399/functions/fstat.html
    • 来自the docLibrary implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability)。仅保证支持SEEK_CURSEEK_SET
    【解决方案2】:
    if( fseek(file,position,SEEK_SET)!=0 || ftell(file) != position )
    {
      throw std::runtime_error("can't seek to specified position");
    }
    

    【讨论】:

    • 这不能保证有效。 ftell() 可以返回文件长度之外的位置。
    【解决方案3】:

    根据manhttp://linuxmanpages.com/man3/fseek.3.phpfseek在出错的情况下返回非零值,唯一可能出现的错误是:

    EBADF 指定的流不是可搜索的流。
    EINVAL fseek() 的 whence 参数不是 SEEK_SET、SEEK_END 或 SEEK_CUR。

    对于lseek,超出文件结尾可能不会被视为错误。但是,紧随其后调用feof 可能表示文件外情况。

    【讨论】:

    • 如果我没记错的话,eof 状态只能保证在读或写时触发。
    【解决方案4】:

    在文件末尾处寻找不是错误。如果写入该偏移量,文件将扩展为空字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 2013-01-08
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多