文件定位

简介: 文件定位

文件打开时,会将文件偏移量设置为指向文件开始,以后每次读写将自动对其进行调整,以指向已读或已写数据后的下一字节。这一点,与标准I/O中的流的定位是一样的。

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);点击复制复制失败已复制


参数 fd 指代已打开的文件,参数 whence 用来设置定位的位置,可以设置 3 种模式: SEEK_SETSEEK_CURSEEK_END ,分别表示定位到文件的开始处当前位置以及末尾offset 依然表示在第三个参数定位的基础上再次发生偏移。函数的返回值为当前定位的位置相对于文件开始处的偏移量。


示例

文件数据的复制

从一个文件(源文件)中读取最后 10KB 的数据并复制到另一个文件中(目标文件)。源文件以只读的方式打开,目标文件以只写的方式打开,若目标文件不存在,可以创建并设置权限的初始值为 0664 (文件所属用户可读写,文件所属组和其他用户只能读)。

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
#define SRC_FILE "src_file"
#define DEST_FILE "dest_file"
#define OFFSET 10240
#define errlog(errmsg)                                                         \
  perror(errmsg);                                                              \
  printf("--%s--%s--%d--\n", __FILE__, __FUNCTION__, __LINE__);                \
  return -1;
int main(int argc, const char *argv[]) {
  int fds, fdd;
  unsigned char buf[BUFFER_SIZE];
  ssize_t read_led;
  if ((fds = open(SRC_FILE, O_RDONLY)) < 0) {
    errlog("open error");
  }
  if ((fdd = open(DEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0664)) < 0) {
    errlog("open error");
  }
  lseek(fds, -OFFSET, SEEK_END);
  while ((read_led = read(fds, buf, sizeof(buf))) > 0) {
    write(fdd, buf, read_led);
  }
  close(fds);
  close(fdd);
  return 0;
}点击复制复制失败已复制


文件读写位置的定位确定之后,程序就可以通过定位操作完成文件数据的截取或合并等问题。


生成空洞文件

在笔记文件的长度中介绍了空洞文件,这里我们演示如何生成一个空洞文件。

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define N 32
int main(int argc, const char *argv[]) {
  int fd;
  char buf1[N] = "abcdefg";
  char buf2[N] = "hijklmn";
  fd = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);
  write(fd, buf1, strlen(buf1));
  lseek(fd, 65536, SEEK_CUR);
  write(fd, buf2, strlen(buf2));
  return 0;
}点击复制复制失败已复制


上述代码通过在文件数据末尾,进行重新读写位置的定位(代码选择偏移 65536 字节),偏移之后再写入数据,则会在中间形成没有数据的空洞。


编译运行,查看生成的 test.txt 文件:

$ gcc main.c && ./a.out 
$ od -c test.txt
0000000   a   b   c   d   e   f   g  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0200000  \0  \0  \0  \0  \0  \0  \0   h   i   j   k   l   m   n
0200016点击复制复制失败已复制


提示

test.txt 文件在系统中显示为 65.5kB

目录
相关文章
定位有几种,他们的特点分别是什么? 是相对于什么进行定位的?
定位有几种,他们的特点分别是什么? 是相对于什么进行定位的?
84 0
|
3月前
定位
【8月更文挑战第25天】定位。
49 3
|
1月前
定位有几种,他们的特点分别是什么?是相对于什么进行定位的?
定位有几种,他们的特点分别是什么?是相对于什么进行定位的?
18 0
|
2月前
静态定位和固定定位
静态定位和固定定位。
31 1
|
6月前
|
存储 Python Windows
文件位置标记与定位:概念、方法与实现
文件位置标记与定位:概念、方法与实现
99 0
|
6月前
|
API Python
文件位置标记及其定位
文件位置标记及其定位
60 2
|
IDE 前端开发 安全
使用xpath定位遇到的坑
使用xpath定位遇到的坑
244 0
|
XML 数据格式 开发者
|
存储 中间件 测试技术
如何及时定位到非必现问题?
自定义channel;区分哪个环境中使用自定义的channel;使用优雅的 monolog 驱动
168 0
如何及时定位到非必现问题?