改变文件大小: ftruncate
文件偏移: lseek
文件描述符的复制:dup、dup2
lseek:偏移
lseek 的返回值:当前光标的位置。
lseek结合了两个功能。正常返回正值。-1失败。
SEEK_SET
SEEK_CUR
SEEK_END
例子1:
#include "func.h"
int main(int argc,char* argv[]){
if(argc!=2){
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fd=open(argv[1],O_RDWR);
if(-1==fd){
perror("open");
return -1;
}
int ret=lseek(fd,6,SEEK_SET); //相对于开头偏移6个
if(-1==ret){
perror("lseek");
return -1;
}
printf("ret=%d\n",ret);
char buf[128]={0};
read(fd,buf,sizeof(buf));
printf("buf=%s\n",buf);
return 0;
}
例子2:文件空洞
利用该函数可以实现文件空洞(对一个新建的空文件,可以定位到偏移文件开头1024个字节的地方,在写入一个字符,则相当于给该文件分配了1025个字节的空间,形成文件空洞)通常用于多进程间通信的时候的共享内存。
#include "func.h"
int main(int argc,char* argv[]){
if(argc!=2){
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fd=open(argv[1],O_RDWR|O_CREAT,0666);
if(-1==fd){
perror("open");
return -1;
}
lseek(fd,1024,SEEK_SET);
write(fd,"a",1);
close(fd);
return 0;
}
ftruncate();改变文件大小。
例子1:
#include "func.h"
int main(int argc,char* argv[]){
if(argc!=2){
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fd=open(argv[1],O_RDWR); //一定要有写权限。
if(-1==fd){
perror("open");
return -1;
}
int ret=ftruncate(fd,10);
if(-1==ret){
perror("ftruncate");
return -1;
}
return 0;
}
也可以实现文件空洞
dup、dup2
操作系统向外提供很多接口。提供的所有接口,都成为系统调用。
函数有的封装了系统调用,有的没有封装系统调用。
#include "func.h"
int main(int argc,char* argv[]){
if(argc!=2){
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fd=open(argv[1],O_RDWR);
if(-1==fd){
perror("open");
return -1;
}
printf("fd=%d\n",fd);
int fd1=dup(fd);
close(fd);
printf("fd1=%d\n",fd1);
char buf[128]={0};
read(fd1,buf,sizeof(buf));
printf("buf=%s\n",buf);
return 0;
}
#include "func.h"
int main(int argc,char* argv[]){
if(argc!=3){
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fda=open(argv[1],O_RDWR); //fda指向argv[1]
if(-1==fda){
perror("open");
return -1;
}
int fdb=open(argv[2],O_RDWR); //fdb指向argv[2]
if(-1==fdb){
perror("open");
return -1;
}
int fdbb=dup(fdb); //fdbb也指向argv[2]
int fdaa=dup2(fda,fdb); //把fda的内容拷给fdb,
printf("fda=%d,fdb=%d,fdaa=%d,fdbb=%d\n",fda,fdb,fdaa,fdbb);
char buf[128]={0};
read(fdb,buf,sizeof(buf));
printf("buf=%s\n",buf);
memset(buf,0,sizeof(buf));
read(fdbb,buf,sizeof(buf));
printf("buf=%s\n",buf);
return 0;
}
int fd;
fd=open(); fd=3 指向了一块结构体数据(文件描述符,相当于文件指针)。
fd1=dup(fd); //fd1=4,但是
引用计数:有几个指向了同一个文件。
dup有时会用在一些特定的场合,如下:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{
if(argc!=2)
{
write(STDOUT_FILENO,"error args\n",11);
return -1;
}
int fd=open(argv[1],O_RDWR|O_CREAT,0666);
if(-1==fd)
{
perror("open");
return -1;
}
printf("fd=%d\n",fd);
printf("\n"); //必不可少
close(1);//close(STDOUT_FILENO); //关闭标准输出
int fd1=dup(fd); //这样fd1就是1号了。而且fd1与fd指向同一文件。
close(fd);
printf("fd1=%d\n",fd1);
printf("how are you,I want to write log\n"); //后面就不用往标准输出写内容了。
return 0;
}
dup2(3,4); //3指向一个文件A,4指向一个文件B。执行后:4的位置也指向了A。
#include "func.h"