对于每个打开的文件,系统都会记录它的读写位置偏移量,我们也把这个读写位置偏移量称为读写偏移量,Linux
中可使用系统函数
lseek
来修改文件偏移量
(
读写位置
)
中可使用系统函数
lseek
来修改文件偏移量
(
读写位置
)
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
fd:
文件描述符。
文件描述符。
offset:
偏移量,以字节为单位。
偏移量,以字节为单位。
whence:
用于定义参数
offset
偏移量对应的参考值,该参数为下列其中一种(宏定义):
用于定义参数
offset
偏移量对应的参考值,该参数为下列其中一种(宏定义):
SEEK_SET:读写偏移量将指向
offset
字节位置处(从文件头部开始算);
offset
字节位置处(从文件头部开始算);
SEEK_CUR:读写偏移量将指向当前位置偏移量
+ offset
字节位置处,
offset
可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;
+ offset
字节位置处,
offset
可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;
SEEK_END:读写偏移量将指向文件末尾 + offset
字节位置处,同样
offset
可以为正、也可以为负,如果是正数表示往后偏移、如果是负数则表示往前偏移。
字节位置处,同样
offset
可以为正、也可以为负,如果是正数表示往后偏移、如果是负数则表示往前偏移。
返回值:成功将返回从文件头部开始算起的位置偏移量(字节为单位),也就是当前的读写位置;发生错误将返回-1,并设置errno值。
应用场景1. 文件的“读”、“写”使用同一偏移位置。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(void)
{
int fd, n;
char msg[] = "It's a test for lseek\n";
char ch;
fd = open("lseek.txt", O_RDWR|O_CREAT, 0644);
if(fd < 0){
perror("open lseek.txt error");
exit(1);
}
write(fd, msg, strlen(msg)); //使用fd对打开的文件进行写操作,问价读写位置位于文件结尾处。
lseek(fd, 0, SEEK_SET); //修改文件读写指针位置,位于文件开头。 注释该行会怎样呢?
while((n = read(fd, &ch, 1))){
if(n < 0){
perror("read error");
exit(1);
}
write(STDOUT_FILENO, &ch, n); //将文件内容按字节读出,写出到屏幕
}
close(fd);
return 0;
}
应用场景2:使用lseek获取文件大小
通过
lseek
获取文件的大小:
lseek(fd, 0, SEEK_END);
lseek
获取文件的大小:
lseek(fd, 0, SEEK_END);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(void)
{
int fd;
fd = open("lseek.txt", O_RDWR);
if(fd < 0){
perror("open lseek.txt error");
exit(1);
}
int len = lseek(fd, 0, SEEK_END);
if(len == -1){
perror("lseek error");
exit(1);
}
printf("file size = %d\n", len);
close(fd);
return 0;
}
应用场景3:使用lseek拓展文件大小:要想使文件大小真正拓展(比较野,不建议),必须引起IO操作。(即要write入)
使用 lseek 拓展文件:write 操作才能实质性的拓展文件。单 lseek 是不能进行拓展的。
一般:write(fd, “a”, 1)
od -tcx filename
查看文件的
16
进制表示形式
查看文件的
16
进制表示形式
od -tcd filename
查看文件的
10
进制表示形式
查看文件的
10
进制表示形式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(void)
{
int fd = open("./ysy.c",O_RDWR);
if(fd == -1)
{
perror("open error");
exit(1);
}
int len = lseek(fd, 100, SEEK_END);
if(len == -1)
{
perror("lseek error");
exit(1);
}
printf("file size=%d\n",len);
int ret = write(fd,"\0",1);
printf("%d\n",ret);
close(fd);
return 0;
}
使用 truncate 函数,直接拓展文件。 int ret = truncate
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
这两个函数的区别在于:ftruncate()
使用文件描述符
fd
来指定目标文件,而
truncate()
则直接使用文件路径 path
来指定目标文件,其功能一样。这两个函数都可以对文件进行截断操作,将文件截断为参数 length
指定的字节长度,什么是截断?如果文件目前的大小大于参数 length
所指定的大小,则多余的数据将被丢失,类似于多余的部分被“砍”掉了;如果文件目前的大小小于参数 length
所指定的大小,则将其进行扩展,对扩展部分进行读取将得到空字节”\0″
。
使用文件描述符
fd
来指定目标文件,而
truncate()
则直接使用文件路径 path
来指定目标文件,其功能一样。这两个函数都可以对文件进行截断操作,将文件截断为参数 length
指定的字节长度,什么是截断?如果文件目前的大小大于参数 length
所指定的大小,则多余的数据将被丢失,类似于多余的部分被“砍”掉了;如果文件目前的大小小于参数 length
所指定的大小,则将其进行扩展,对扩展部分进行读取将得到空字节”\0″
。
使用 ftruncate()函数进行文件截断操作之前,必须调用
open()
函数打开该文件得到文件描述符,并且必 须要具有可写权限,也就是调用 open()
打开文件时需要指定
O_WRONLY
或
O_RDWR
。
open()
函数打开该文件得到文件描述符,并且必 须要具有可写权限,也就是调用 open()
打开文件时需要指定
O_WRONLY
或
O_RDWR
。
调用这两个函数并不会导致文件读写位置偏移量发生改变,所以截断之后一般需要重新设置文件当前的读写位置偏移量,以免由于之前所指向的位置已经不存在而发生错误(譬如文件长度变短了,文件当前所指向的读写位置已不存在)。
调用成功返回 0
,失败将返回
-1
,并设置
errno
以指示错误原因。
,失败将返回
-1
,并设置
errno
以指示错误原因。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void) {
int fd;
/* 打开 file1 文件 */
if (0 > (fd = open("./file1", O_RDWR))) {
perror("open error");
exit(-1);
}
/* 使用 ftruncate 将 file1 文件截断为长度 0 字节 */
if (0 > ftruncate(fd, 0)) {
perror("ftruncate error");
exit(-1);
}
/* 使用 truncate 将 file2 文件截断为长度 1024 字节 */
if (0 > truncate("./file2", 1024)) {
perror("truncate error");
exit(-1);
}
/* 关闭 file1 退出程序 */
close(fd);
exit(0);
}
今天的文章linux中lseek函数_shell ls命令分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/58269.html