ftell 在超过 2GB 的位置 [英] ftell at a position past 2GB

查看:46
本文介绍了ftell 在超过 2GB 的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 32 位系统上,如果以二进制模式打开的文件的当前位置指示器超过 2GB 点,ftell 返回什么?在 C99 标准中,这是 未定义的行为,因为 ftell 必须返回一个 long int(最大值为 2**31-1)?

On a 32-bit system, what does ftell return if the current position indicator of a file opened in binary mode is past the 2GB point? In the C99 standard, is this undefined behavior since ftell must return a long int (maximum value being 2**31-1)?

推荐答案

on long int

long int 应该是至少 32 位,但 C99 标准并没有将其限制为 32 位.C99 标准确实提供了方便的类型,例如 int16_t &int32_t 等映射到目标平台的正确位大小.

on long int

long int is supposed to be AT LEAST 32-bits, but C99 standard does NOT limit it to 32-bit. C99 standard does provide convenience types like int16_t & int32_t etc that map to correct bit sizes for a target platform.

ftell()fseek() 在绝大多数 32 位架构系统上被限制为 32 位(包括符号位).因此,当有大文件支持时,您会遇到这个 2GB 问题.

ftell() and fseek() are limited to 32 bits (including sign bit) on the vast majority of 32-bit architecture systems. So when there is large file support you run into this 2GB issue.

POSIX.1-2001 和 fseekftell 的 SysV 函数是 fseekoftello 因为它们使用off_t 作为偏移量的参数.

POSIX.1-2001 and SysV functions for fseek and ftell are fseeko and ftello because they use off_t as the parameter for the offset.

您确实需要使用 -D_FILE_OFFSET_BITS=64 定义编译或在包含 stdio.h 之前在某处定义它以确保 off_t 是 64 位.

you do need to define compile with -D_FILE_OFFSET_BITS=64 or define it somewhere before including stdio.h to ensure that off_t is 64-bits.

cert.org 安全编码指南.

C99 说long int 必须至少 32 位它并没有说它不能更大

C99 says long int must be at least 32-bits it does NOT say that it cannot be bigger

在 x86_64 架构上尝试以下操作:

try the following on x86_64 architecture:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *fp;
    fp = fopen( "test.out", "w");
    if ( !fp ) 
        return -1;
    fseek(fp, (1L << 34), SEEK_SET);
    fprintf(fp, "
hello world
");
    fclose(fp);
    return 0;
}

请注意,1L 只是一个 long,这将产生一个 17GB 的文件并将 " hello world " 粘贴到它的结束.您可以通过简单地使用 tail -n1 test.out 或显式使用来验证是否存在:

Notice that 1L is just a long, this will produce a file that's 17GB and sticks a " hello world " to the end of it. Which you can verify is there by trivially using tail -n1 test.out or explicitly using:

dd if=test.out skip=$((1 <<25))

dd if=test.out skip=$((1 << 25))

请注意,dd 通常使用 (1 << 9) 的块大小,因此 34 ​​- 9 = 25 将转储 ' hello world '

Note that dd typically uses block size of (1 << 9) so 34 - 9 = 25 will dump out ' hello world '

这篇关于ftell 在超过 2GB 的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆