lseek
lseek()用来控制文件的读写位置。(移动读写指针位置)。
每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。
用法:
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
/*lseek成功返回偏移量,失败返回-1*/
whence:
- SEEK_SET 将读写位置指向文件头后再增加offset个位移量
- SEEK_CUR 以目前的读写位置往后增加offset个位移量
- SEEK_END 将读写位置指向文件尾后再增加offset个位移量
实例:
1)用lseek拓展一个空文件abc。
lseek_test1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main(void)
{
int fd;
fd = open("abc", O_RDWR);
if(fd < 0)
{
perror("open abc");
exit(-1);
}
/* 0x1000相当于4096字节 */
lseek(fd, 0x1000, SEEK_SET);
/* 扩展一个文件,一定要有一次写操作 */
write(fd, "a", 1);
close(fd);
return 0;
}
2)lseek获取一个文件的大小。
lseek_test2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd;
fd = open("hello", O_RDONLY);
if(fd < 0)
{
perror("open hello");
exit(-1);
}
printf("%d\n", lseek(fd, 0, SEEK_END));
close(fd);
return 0;
}
gcc lseek_test2.c -o lseek_test2
fcntl
fcntl获取或设置文件访问控制属性。可改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这 些标志称为File Status Flag),而不必重新open文件。
用法:
#include <unistd.h>
#include <fcntl.h>
/* 可变参函数 */
int fcntl(int fd, int cmd, ... /* arg */ );
可变参数的类型和个数取决于前面的 cmd参数。
File Status Flag:
- F_GETFL 获得文件状态标志
- F_SETFL 设置文件状态标志
实例:
fcntl改变一个已打开文件的属性。
对非阻塞读终端代码修改。
...
#define MSG_TRY "try again\n"
int main(void)
{
int flags, n;
char buf[10];
/* 这样就不用重新open /dev/tty 设置O_NONBLOCK*/
flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK;
if(fcntl(STD_FILENO, F_SETFL, flags) == -1)
{
perror("fcntl");
exit(1);
}
tryagain:
......
}