一、使用标准I/O函数
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
unsigned long long file_size = 0;
int fd;
fd = open(argv[1], O_RDWR | O_CREAT | O_SYNC , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ((file_size = lseek(fd, 0, SEEK_END)) < 0) {
perror("Error seeking to file end");
return EXIT_FAILURE;
}
printf("file_size[%lld]\n", file_size);
close(fd);
return 0;
}
lseek访问一个大于2GB的文件,结果:
# ./lseek_test cn_office_professional_plus_2019_x86_x64_dvd.iso
file_size[-1]
因为正常情况下lseek只支持-2GB~+2GB的文件定位
二、增加O_LARGEFILE参数支持大文件定位
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
unsigned long long file_size = 0;
int fd;
fd = open(argv[1], O_RDWR | O_CREAT | O_SYNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ((file_size = lseek(fd, 0, SEEK_END)) < 0) {
perror("Error seeking to file end");
return EXIT_FAILURE;
}
printf("file_size[%lld]\n", file_size);
close(fd);
return 0;
}
编译时需要增加_LARGEFILE64_SOURCE宏定义,否则编译会报错;同时需要增加_FILE_OFFSET_BITS=64宏定义,否则lseek依然无法定位超过2G的文件
arm-xilinx-linux-gnueabi-gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 lseek.c -o lseek_test
测试结果:
# ./lseek_test cn_office_professional_plus_2019_x86_x64_dvd.iso
file_size[3775004672]
三、使用lseek64定位文件
不需要指定-D_FILE_OFFSET_BITS=64也可以操作超过2G的文件
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
unsigned long long file_size = 0;
int fd;
fd = open(argv[1], O_RDWR | O_CREAT | O_SYNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ((file_size = lseek64(fd, 0, SEEK_END)) < 0) {
perror("Error seeking to file end");
return EXIT_FAILURE;
}
printf("file_size[%lld]\n", file_size);
close(fd);
return 0;
}
arm-xilinx-linux-gnueabi-gcc -D_LARGEFILE64_SOURCE lseek.c -o lseek_test