32位arm使用lseek定位大于2GB的文件

一、使用标准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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以利用lseek函数的空洞文件原理来实现对文件的分片拷贝。空洞文件是指文件中存在一些数据块没有被实际占用,这些数据块被称为空洞。lseek函数可以用来改变文件的读写位置,并且当设置的位置超过文件的大小时,文件会被自动扩展,并在扩展的空间中填充0。 下面是一个使用lseek函数进行分片拷贝的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> void copyFile(char* srcPath, char* destPath, off_t start, off_t size) { int srcFd = open(srcPath, O_RDONLY); int destFd = open(destPath, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (srcFd == -1 || destFd == -1) { perror("Failed to open file"); exit(1); } off_t fileSize = lseek(srcFd, 0, SEEK_END); lseek(srcFd, start, SEEK_SET); char buffer[1024]; off_t remaining = size; while (remaining > 0) { ssize_t bytesRead = read(srcFd, buffer, sizeof(buffer)); if (bytesRead > remaining) { bytesRead = remaining; } ssize_t bytesWritten = write(destFd, buffer, bytesRead); if (bytesWritten != bytesRead) { perror("Failed to write file"); exit(1); } remaining -= bytesRead; } close(srcFd); close(destFd); } int main() { char* srcPath = "source_file.txt"; char* destPath = "destination_file.txt"; off_t start = 100; // 起始位置 off_t size = 200; // 拷贝的大小 copyFile(srcPath, destPath, start, size); return 0; } ``` 上述代码中,copyFile函数用于实现文件的分片拷贝。它首先打开源文件和目标文件,然后使用lseek函数将源文件的读写位置移动到指定的起始位置start。接下来,使用read函数从源文件中读取数据到缓冲区buffer中,然后使用write函数将缓冲区中的数据写入目标文件。这个过程会循环执行,直到拷贝指定大小的数据或者源文件的数据读取完毕。最后,关闭源文件和目标文件文件描述符。 你可以根据实际需求修改代码中的文件路径、起始位置和拷贝大小等参数。注意,这里的起始位置和拷贝大小都是以字节为单位的偏移量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值