背景

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

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

Linux C 读写超过2G的大文件 注意事项的更多相关文章

  1. U盘无法拷贝超过4G的大文件

    现在U盘的容量越来越大了,8G闪存满天飞,几乎已成“标配”,市面上再见难觅64M.128M等U盘的踪迹,可是细心的你也许已经发现,即使是8G或更大体积的U盘,仍然不能拷贝存储体积超过4G的大文件,这是 ...

  2. linux下使用split 来分割大文件

    linux下使用split 来分割大文件 2010-07-27 15:46:27|  分类: 技术文稿 |  标签:split  分割  linux   |字号 订阅   平常都是使用ssh来进行远程 ...

  3. 利用Linux的硬连接删除MySQL大文件

    利用Linux的硬连接删除MySQL大文件 http://blog.csdn.net/wxliu1989/article/details/22895201 原理:硬链接基础当多个文件共同指向同一ino ...

  4. 【转】码云source tree 提交超过100m 为什么大文件推不上去

    码云source tree 提交超过100m 为什么大文件推不上去 2017年01月12日 16:50:51 阅读数:7634 git -c diff.mnemonicprefix=false -c ...

  5. Linux如何使用cURL分割下载大文件

    Linux如何使用cURL分割下载大文件 - 51CTO.COM http://os.51cto.com/art/201508/489368.htm

  6. linux磁盘空间满了 但是没有大文件

    很常见的一个问题 linux磁盘空间满了 但是没有大文件 解决思路: 1.用df 检查发现/根目录可用空间为0 [root@/]#df -h 2.用du检查发现各目录占用的空间都很少,有约3G的空间莫 ...

  7. Linux 查看磁盘容量、查找大文件、查找大目录

    Linux 查看磁盘容量.查找大文件.查找大目录 磁盘统计 查看磁盘使用情况 df -h 文件统计 查找/home 目录下大于800M的文件 find /home -type f -size +800 ...

  8. linux(centos8):用fallocate快速生成大文件

    一,fallocate的用途? 1,用途 我们有时需要用大文件来测试下载速度, 有时需要用大文件来覆盖磁盘空间, 如果在网上搜索,很多文章讲的是使用dd等工具, 事实上linux系统已经内置了生成大文 ...

  9. Linux使用dd命令快速生成大文件(转)

    dd命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1000M的test文件,文件内容为全0(因从/dev/zero ...

  10. linux磁盘内存满了?删除大文件依然不起作用

    好久没有更新博客了,但并不代表自己没有遇到技术问题了.遇到了一大堆,也解决了一大堆.只是没有记下来的欲望了,似乎大脑就这样,忘不掉.啥都忘不掉了,即使忘掉了也知道如何百度了. 查看目录大小命令 du命 ...

随机推荐

  1. Solution Set - 点分治

    A[POJ1741].给定一棵树,边有权,求长度不超过\(k\)的路径数目. B[HDU4871].给定一张图,边有权,求它的最短路径树上恰含\(k\)个点的路径中最长路径的长度及数目. C[HDU4 ...

  2. 1、Linux基础

    1.centos 安装 2.磁盘分区表示方法 1.2.3.4:主分区,最多4个主分区,后数据为逻辑分区 主分区可以激活,但一个硬盘只能激活一个主分区 被激活的主分区就是用来引导操作系统的主分区 扩展分 ...

  3. 09. rails 创建user用户列表

    gem添加分页的依赖 #列表分页 gem 'will_paginate', '~> 3.0.pre2' bundle 安装依赖 用户列表控制器 before_filter :auth_user, ...

  4. Threading Programming Guide:One

    苹果支持的产生线程的方式 Operation Object 使用OperationQueue,具体可以参考:Concurrency Programming Guide GCD 使用诸如dispatch ...

  5. 网络性能评估工具Iperf详解

    一.网络性能评估工具Iperf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性能的基础,但是由于网络设计不合理.网络存在安全漏洞等原因,都会导致网络带宽利用率不高.要找到网络 ...

  6. Python:当函数做为参数时的技巧

    我们之前在<Python技法3: 匿名函数.回调函数.高阶函数>中提到,可以通过lambda表达式来为函数设置默认参数,从而修改函数的参数个数: import math def dista ...

  7. vulnhub靶场 --> JANGOW: 1.0.1

    靶机下载地址 JANGOW: 1.0.1 << 点我下载 开始打靶 IP发现 nmap扫描网段发现靶机ip:192.168.111.140 端口发现 对靶机进行常规端口扫描 访问网站 访问 ...

  8. Python 数据降级(重采样)

    在数据处理中,经常有高频数据转成低频,秒级数据转成分钟.小时数据等.我们将讨论以下方法: 使用 Pandas 的 resample 方法: 示例:将天数据转化成月数据. 代码示例: import pa ...

  9. .NET集成DeveloperSharp实现http网络请求&与其它工具的比较

    爆了,爆了,DeveloperSharp系列近期又被制造业ERP.民航飞行App.建筑BIM.电力掌上营业厅.等多家大型采用,站在巨人的肩膀上你能走的更远. 支持.Net Core2.0及以上,支持. ...

  10. cmder右键打开方式

    第一步: 新打开一个cmder窗口 第二步: 输入: Cmder.exe /register user 或 Cmder.exe /register all 第三步: 回车执行命令