标题: 32-bits程序访问文件0x80000000及以上偏移 创建: 2016-12-10 14:09 更新: 2018-11-27 09:37 链接: https://scz.617.cn/unix/201612101409.txt 参看: open(2) mmap(2) lseek(2) lseek64(3) feature_test_macros(7) lseek()第2形参offset的数据类型是off_t。对于32-bits架构,off_t缺省对应32位 有符号整数,其最大值是0x7fffffff。如果我们需要在32-bits程序中访问0x80000000 及以上偏移,会遇上很多坑,而64-bits程序不存在这个问题。 我给个小结,为满足原始需求,有3种办法: -------------------------------------------------------------------------- a) #define _FILE_OFFSET_BITS 64 open lseek read 这是推荐用法,此时不需要_GNU_SOURCE、_LARGEFILE64_SOURCE、O_LARGEFILE、 lseek64 -------------------------------------------------------------------------- b) #define _LARGEFILE64_SOURCE open O_LARGEFILE lseek64 read 此时必须_LARGEFILE64_SOURCE、O_LARGEFILE、lseek64。假设已经O_LARGEFILE,但 不用lseek64,此时lseek不会报错,后面的read会报"Invalid argument" O_LARGEFILE必须辅以lseek64。分两次lseek,不能解决问题。所谓分两次lseek,指 lseek( fd, ( off_t )0x7fffffff, SEEK_SET ) lseek( fd, ( off_t )(off-0x7fffffff), SEEK_CUR ) 这种情况下,第二次lseek会报"Value too large for defined data type" 如果想直接使用lseek,应该定义_FILE_OFFSET_BITS宏 定义_GNU_SOURCE之后会隐式定义_LARGEFILE64_SOURCE -------------------------------------------------------------------------- c) open mmap memcpy mmap的形参offset不需要_FILE_OFFSET_BITS宏,尽管其数据类型是off_t,open时也 不需要O_LARGEFILE,因此不需要_LARGEFILE64_SOURCE宏 --------------------------------------------------------------------------