• Linux C 读写超过2G的大文件 注意事项


    背景

    在项目中做大文件的增量读写,遇到了问题:

    fopen : Value too large for defined data type.
    

    习惯性地根据这个提示查阅的有关资料显示:
    1)工具链太老了:海思的工具链我目前找不到更换的方法,也为了稳定性,不再增加新的ulibc库
    2)文件系统的 inde是 64位的:查看了 cat /proc/fs/{文件系统类型}/{设备名}/options,发现一切正常

    显然,这样的结果并不能让我满足。

    Linux C/C++ 大文件读写下编程实现的不同

    由于上文的方向不对,于是我换了个思路,直接根据需求查找: "Linux C 读写大文件"

    了解到了有关信息:

    • Linux默认环境下打开、读、写超过2G的文件会返回错误。定义#define _FILE_OFFSET_BITS 64宏可以突破这个限制,对read/write和fread/fwrite同时有效。(注意必须定义在<stdio.h>之前。至此,open文件算是没有问题了)
    #define _LARGEFILE_SOURCE
    #define _LARGEFILE64_SOURCE
    #define _FILE_OFFSET_BITS 64
    

    细心的读者肯定注意到了,还有2个宏,这2个宏是与 fpos_t 有关的;而这个 fpos_t 与 操作文件偏移量有关。

    传统 偏移操作 : fseek() + ftell()

        fseek(fp,0,SEEK_END);
        length = ftell(fp);
        fseek( fp, 0, SEEK_SET);
        printf("%ld", length );
    

    处理大文件时,ftell 的返回值有问题:要么是-1,要么是_length数据类型的最大值,总之都是不对的。

    而正确的方式应该是 使用 : fseek() + fgetpos()fsetpos()

    解决办法是:

       fpos_t pos;
       fseek(fp,0,SEEK_END);
       fgetpos(fp,&pos);
       fseek( fp, 0, SEEK_SET);
    

    fseek、ftell() 与 fgetpos()、fsetpos()

    我们都知道ftell与fseek一起使用;而fsetpos与fgetpos也要结合fseek使用。

    ftell与fseek返回的是长整数,而后面两个则是返回一个新类型:fpos_t

    ftell() 用长整型表示文件内的偏移 (位置), 因此, 偏移量被 限制在 20 亿 (231-1) 以内。

    而新的 fgetpos() 和 fsetpos() 函数使用 了一个特殊的类型定义 fpos_t 来表示偏移量 (这个类型的值的内容与 _LARGEFILE_SOURCE、_LARGEFILE64_SOURCE 宏有关)

    因此, fgetpos() 和 fsetpos 可以表示任意大小的文件偏移,fgetpos() 和 gsetpos() 也可以用来记录多字节流式文件的状态。

    基于 mmap 的 大文件读写

    我在查阅资料的时候,也发现 可以通过 mmap 的方式来操作大文件(以前读写FrameBuffer的时候就用到了这种方式)

    https://blog.csdn.net/hanqdi_/article/details/104273381

    https://www.jb51.net/article/172103.htm

    如果说我的文章对你有用,只不过是我站在巨人的肩膀上再继续努力罢了。
    若在页首无特别声明,本篇文章由 Schips 经过整理后发布。
    博客地址:https://www.cnblogs.com/schips/
  • 相关阅读:
    一年三百六十日,需求业务严相逼
    新博客测试
    教务流水账
    暗流涌动的话“用户体验”
    文档那些事儿
    jforum(2)中文乱码的解决方式
    jmeter笔记(4)测试上传附件
    jmeter笔记(2)组件介绍
    jmeter笔记(5)参数化CSV Data Set Config
    jmeter笔记(6)参数化函数助手
  • 原文地址:https://www.cnblogs.com/schips/p/linux_c_read_write_file_size_over_2g.html
Copyright © 2020-2023  润新知