Read 23 byte data:HelloWorld
HelloMaQian
## 四、关于lseek
lseek用于设置文件指针的位置,同时也可以查看当前指针所处的位置。
如果设置的文件指针超过了文件范围,系统将会给文件申请更多的内存空间来存储这些超出的文件数据,但这要求系统要在指针所指向的位置进行一次写操作。
include "apue.h"
include <fcntl.h>
int main() {
int fd, ret;
const char *s1 = "abcdefghij";
const char *s2 = "ABCDEFGHIJ";
fd = open("test.hole", O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (-1 == fd)
err_sys("open file error");
if (write(fd, s1, 10) != 10)
err_sys("write s1 error");
if ((ret = lseek(fd, 0, SEEK_CUR)) < 0)
err_sys("lseek error");
printf("localtion: %d\n", ret); // 打印当前的指针位置 10
if ((ret = lseek(fd, 1000, SEEK_SET)) < 0)
err_sys("lseek error");
printf("localtion: %d\n", ret); // 移动后的位置 1000
if (write(fd, s2, 10) != 10)
err_sys("write s2 error");
close(fd);
return 0;
}
运行程序后输出:
./a.out
localtion: 10
localtion: 1000
ll test.hole
-rwxr-xr-x 1 ma ma 1010 May 18 11:18 test.hole # 文件大小1010字节
### 4.1 使用lseek生成指定大小的文件
根据上面所描述的`lseek`的特性,文件指针超出时会自动申请空间,因此我们可以通过它来生成一个指定大小的文件。
include "apue.h"
include <fcntl.h>
const int BT_SIZE = 1;
const int KB_SIZE = 1 << 10;
const int MB_SIZE = 1 << 20;
const int GB_SIZE = 1 << 30;
/*
- 解析输入的文件大小
- @size 大小字符串1g, 1m, 1k, 1
- @return 返回解析好的字节数
- 失败直接退出程序
*/
int parser_size(const char *size)
{
int i = 0, n = 0;
char ch; // 遍历每一个字符
while ((ch = size[i]))
{
if ((''a'' <= ch && ch <= ''z'') || (''A'' <= ch && ch <= ''Z''))
{
if(size[i + 1])
err_quit("invalid input: %s", size);
switch (ch)
{
case ''b'':
case ''B'':
return BT_SIZE * n;
case ''k'':
case ''K'':
return KB_SIZE * n;
case ''m'':
case ''M'':
return MB_SIZE * n;
case ''g'':
case ''G'':
return GB_SIZE * n;
default:
err_quit("invalid input: %c", ch);
}
}
else if (''0'' <= ch && ch <= ''9'')
{
n = 10 * n + ch - ''0'';
}
else
{
err_quit("invalid input: %s", size);
}
i++;
}
return n;
}
int main(int argc, char **argv)
{
if (argc < 3)
err_quit("Usage: ./mkfile filename size");
int sz = parser_size(argv[2]);
int fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (-1 == fd)
err_sys("crate file error");
// 移动到指定位置的前一个字节
if (-1 == lseek(fd, sz - 1, SEEK_SET))
err_sys("create file error");
// 写入一个字节申请内存块
if (1 != write(fd, " ", 1))
err_sys("write data error");
close(fd);
return 0;
}
根据输入即可生成指定大小的文件:
mkdir debug && gcc main.c /apue.* -o debug/app
./debug/app test1 1g
./debug/app test2 2m
./debug/app test3 3k
./debug/app test4 4
ll
total 32K
drwxrwxr-x 2 ma ma 4.0K May 18 14:40 debug
-rw-rw-r-- 1 ma ma 1.7K May 18 14:39 main.c
-rw-rw-r-- 1 ma ma 1.7K May 18 14:35 main.c.orig
-rw-rw-r-- 1 ma ma 311 May 18 14:22 Makefile
-rwxr-xr-x 1 ma ma 1.0G May 18 14:41 test1
-rwxr-xr-x 1 ma ma 2.0M May 18 14:41 test2
-rwxr-xr-x 1 ma ma 3.0K May 18 14:41 test3
-rwxr-xr-x 1 ma ma 4 May 18 14:41 test4
不过对于文件的大小有个限制,文件最多只能`2G+`,因为此时计算出来的`sz`大小会溢出。
此处评论已关闭