C语言之lseek64报Invalid argument根本原因(六十八)
2023-09-14 09:09:58 时间
计算机常用的存储单位:
8 bit = 1 Byte 一字节;
1024B=1KB (KiloByte) 千字节;
1024KB=1MB(MegaByte)兆字节;
1024MB=1GB(GigaByte)吉字节;
1024GB=1TB(TeraByte)太字节;
1024TB=1PB(PetaByte)拍字节;
1024PB=1EB(ExaByte)艾字节;
1024EB=1ZB(ZetaByte)泽字节;
1024ZB=1YB(YottaByte)尧字节;
1024YB=1BB(Brontobyte)珀字节;
1024BB=1 NB(NonaByte) 诺字节;
1024NB=1DB(DoggaByte)刀字节。
1.在32位系统中,open()和lseek()只能打开/位移数据最大为4GB问题
例如创建/访问超过4GB以上需要使用几种方式
open()使用O_LARGEFILE宏
open(argv[1], O_WRONLY | O_CREAT | O_LARGEFILE, 0755);
添加头文件:
//1.lseek64()
//#define _GNU_SOURCE /* for O_DIRECT */
//Or:
//2.lseek64()
#define __USE_FILE_OFFSET64
#define __USE_LARGEFILE64
#define _LARGEFILE64_SOURCE
使用fopen64()函数
同样添加头文件
//1.lseek64()
//#define _GNU_SOURCE /* for O_DIRECT */
//Or:
//2.lseek64()
#define __USE_FILE_OFFSET64
#define __USE_LARGEFILE64
#define _LARGEFILE64_SOURCE
2.创建一个超过4GB以上的空文件sample
理论上可以最大创建2^63-1(184467440TB)大小的文件,但是电脑硬盘目前还达不到,集群的话恐怕也难以达到这么大的空间。
如果传入的是(1ull<<63) - 1,系统会报错:lseek: Invalid argument(无效参数),因为它远远目前硬盘的所承受的大小,所以传入lseek64()函数的offset太大了,甚至达到几百TB,远远超出一般硬盘的容量,所以报无效参数,这才是根本原因,如果传入的很大的参数说明,传入的参数是有问题的。
如下创建大文件的demo:
#define _LARGEFILE64_SOURCE
#include<stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char** argv){
if(argc < 2){
printf("Usage: %s [file]\n", argv[0]);
return -1;
}
int fd = open(argv[1], O_WRONLY | O_CREAT | O_LARGEFILE, 0755);
printf("2^63 -1 = %lld\n",(1ULL << 43) - 1); //9223372036854775807
printf("2^64 -1 = %llu\n",(1ULL << 64) - 1);//18446744073709551615 = 184467440TB = 184467PB = 184EB
//理论上可以最大创建2^63-1(184467440TB)大小的文件,但是电脑硬盘目前还达不到,集群的话恐怕也难以达到这么大的空间,如果传入的是(1ull<<63) - 1,系统会报错:lseek: Invalid argument(无效参数),因为它远远目前硬盘的所承受的大小.
off_t ret = lseek64(fd, (1ull<<43) - 1, SEEK_SET); //8796093022207 = 8TB //ok
//off_t ret = lseek64(fd, (1ull<<8) - 1, SEEK_SET); //0xFFFFFFFFL = 4GB
if(ret == -1){
perror("lseek");
return -1;
}
write(fd, "\0", 1);
close(fd);
return 0;
}
查看创建成功的空文件
# ls -alh 222.txt
-rwxr-xr-x 1 8.0T 2月 16 00:52 222.txt
注意:我的电脑是4TB,但是却能创建成功的8TB大小的文件,也是不可思议。
但是如果再传入lseek64(fd, (1ull<<44) - 1, SEEK_SET); 就报无效参数。
相关文章
- void loop在c语言中什么意思,C语言中的loop是什么意思,在C语言中loop是什么意思?…[通俗易懂]
- C语言之malloc函数「建议收藏」
- C语言之指针详解编程语言
- const修饰指针的三种效果,C语言const修饰指针详解
- Linux下安装C语言编译器的指南(linux安装c语言)
- 地址在Linux中用C语言获取IP地址(linuxc获取ip)
- 使用MongoDB进行C语言分页操作(mongodbc分页)
- MySQL视频保存C语言技术指南(c mysql视频保存)
- 如何利用C语言编写MySQL编辑器(c mysql编辑器)
- C语言MySQL视频教程,让你快速掌握技能(c mysql教程视频)
- MySQL列表查询实践深度探索C语言实现(c mysql 列表查询)
- 让Oracle数据更便捷C语言实现数据格式转换(c oracle格式转换)
- C语言-字符串函数的实现(四)之strcmp
- 浅谈C语言中结构体的初始化
- 深入解析C语言中typedef的四个用途