我正在读取一个文件格式(TIFF),它从文件的开头有32位无符号偏移量。
不幸的是fseek的原型,通常我会去特定的文件偏移,是:
int fseek ( FILE * stream, long int offset, int origin );
所以偏移是签名的。 我应该如何处理这种情况? 我应该使用不同的function进行搜索吗?
您可以尝试使用lseek64()
( 手册页 )
#define _LARGEFILE64_SOURCE /* See feature_test_macros(7) */ #include #include off64_t lseek64(int fd, off64_t offset, int whence);
同
int fd = fileno (stream);
GNU C lib中的注释- 设置描述符的文件位置
此函数类似于lseek函数。 不同之处在于offset参数的类型为off64_t而不是off_t,这使得32位机器可以处理大于2 ^ 31字节和最多2 ^ 63字节的文件。 必须使用open64打开文件描述符filedes,否则off64_t可能导致的大偏移将导致在小文件模式下出现描述符错误。
当在32位机器上使用_FILE_OFFSET_BITS == 64编译源文件时,该函数实际上以名称lseek可用,因此透明地替换32位接口。
关于fd
和stream
,来自Streams和File Descriptors
由于流是根据文件描述符实现的,因此您可以从流中提取文件描述符,并直接在文件描述符上执行低级操作。 您还可以最初打开连接作为文件描述符,然后创建与该文件描述符关联的流。
在更深入地研究这个问题并考虑其他评论和答案(谢谢)之后,我认为最简单的方法是在偏移量大于2147483647字节时进行两次搜索。 这允许我将偏移保持为uint32_t
并继续使用fseek
。 定位代码是这样的:
// note: error handling code omitted uint32_t offset = ... (whatever it is) if( offset > 2147483647 ){ fseek( file, 2147483647, SEEK_SET ); fseek( file, (long int)( offset - 2147483647 ), SEEK_CUR ); } else { fseek( file, (long int) offset, SEEK_SET ); }
使用64位类型的问题是代码可能在32位架构上运行(除其他外)。 有一个函数fsetpos
使用结构fpos_t
来管理任意大的偏移,但这会带来一系列复杂性。 虽然如果我真的使用任意大尺寸的偏移量, fsetpos
可能有意义,因为我知道最大可能的偏移量是uint32_t,然后双重搜索满足了这种需要。
请注意,此解决方案允许在32位系统上处理所有TIFF文件。 如果您考虑像PixInsight这样的商业程序,这一点很明显。 在32位系统上运行时,PixInsight只能处理小于2147483648字节的TIFF文件。 要处理完整大小的TIFF文件,用户必须在64位计算机上使用64位版本的PixInsight。 这可能是因为PixInsight程序员使用64位类型在内部处理偏移。 由于我的解决方案只使用32位类型,我可以在32位系统上处理全尺寸TIFF文件(只要底层操作系统可以处理大文件)。
以上就是c/c++开发分享fseek到32位无符号偏移量相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/550072.html