回顾:
文件读写 - open() read() write() close() lseek()
Today:
文件其他函数(非读写)
目录操作
文件的函数:dup(int oldfd); dup2(int oldfd,int newfd);
dup() 和 dup2() - 复制文件描述符,但不复制文件表
dup() 和 dup2()的区别: dup()新描述符由系统选择最小的可用值,而dup2()由程序员指定值,如果指定值被使用,强行关闭后使用。
-----------------------------------------------------------
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 int main()
6 {
7 int fd = open("a.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
8 if(fd == -1) perror("open"),exit(-1);
9 int fd2 = dup(fd);//复制描述符,不复制文件表
10 printf("fd=%d,fd2=%d\n",fd,fd2);
11 write(fd,"1",1);
12 write(fd2,"2",1);//如果覆盖 2个偏移量 2个文件表
13 int fd3 = dup2(fd,100);
14 printf("fd3=%d\n",fd3);
15 write(100,"ok",2);
16 int fd4 = open("b.txt",O_RDWR|O_CREAT,0666);//5
17 if(fd4 == -1) perror("open"),exit(-1);
18 int fd5 = dup2(fd,5);//强行关闭fd4
19 write(fd4,"HEHE",4);//写入a.txt,放在ok后面
20 close(fd);close(fd2);
21 }
运行后结果:
fd=3 fd2=4 fd3=100
a.txt = 12okHEHE
-----------------------------------------------------------
fcntl():
int fcntl(int fd,int cmd,...)
参数fd - 一个打开的文件描述符
参数cmd决定了功能:
F_DUPFD(long) 复制文件描述符,类似dup2(),区别:不强行关闭已经使用的描述符,而是取大于等于参数的可用描述符
F_GETFL/F_SETFL 获取/设置 文件描述符的状态,只能获取权限和状态标识,不能获取创建标识,设置时,只能设置O_APPEND
F_SETLK F_SETLKW F_GETLK 文件锁
经验: 与宏变量 做 位与运算 可以得到某一位/某几位,比如:取后8位二进制: & 0xFF
F_SETLK: 加文件锁,文件锁也是存于内存中的,文件锁可以锁定文件的某个部分而不锁定全部
F_SETLKW: 加文件锁,以阻塞方式加文件锁,如果锁不上,会等待,而F_SETLK直接返回错误
F_GETLK: 测试一把锁能否加上
使用文件锁需要结构 flock,成员:
struct flock
{
short l_type;//锁类型,有三种
short l_whence;//锁定起始点的参考位置
int l_start;//锁定起始点的偏移量
int l_len;//锁定的长度(字节数)
pid_t l_pid;//进程ID,GETLK使用,SETLK一般-1即可
};
l_type 包括:
F_RDLCK - 读锁
F_WRLCK - 写锁
F_UNLCK - 释放锁
读锁: 一种共享锁,允许读进程访问,锁定其它进程的写操作
写锁: 一种独占锁(互斥锁),不允许其它进程读写操作
释放锁: 解除之前的锁定,其它进程就可以继续操作。如果不释放锁,只能等到当前进程结束其它进程才能继续操作
l_whence 是锁定的起始点的参考位置,值为:
SEEK_SET SEEK_CUR SEEK_END
l_start 是起始点从参考位置的偏移量
l_whence 和 l_start 联合决定了起始点的位置,比如: l_whence = SEEK_SET l_start = 10,效果就是从头偏移10个做起始点
fcntl()加锁对 read() write()没有任何的约束力,锁定的是 其它进程的加锁行为。因此正确用法应该是:在进程中,读函数调用之前先加读锁,如果能加读锁再读;写函数调用之前先加写锁,如果能加写锁再写。
如果不能读/写直接返回,用F_SETLK;如果想等到能读/写位置,用F_SETLKW
如果读写之前加了锁,读写完成以后一定要释放锁。释放锁的方法:把锁的类型改为F_UNLCK,再调用fcntl()设置即可
文件的其它函数:
stat() / fstat() - 取硬盘文件/目录的各种状态,效果和ls -il 一样。stat()主要用于取文件的大小(不需要open)
C语言中如何描述时间:
1.秒差 time_t 其实就是个整数(当前时间-1970.01.01.00:00)
2.结构 struct tm 有年月日时分秒星期成员
计算机更喜欢time_t,人类看不懂秒差
需要转换函数:localtime()把秒差转结构
ctime() 可以把秒差转字符串(英文习惯)
-----------------------------------------------------------
access() - 判断文件的权限和是否存在
access("a.txt",宏)
R_OK W_OK X_OK - 权限判断
F_OK - 文件是否存在
返回0 代表存在 和 有权限
-------------------------------------
1 #include <stdio.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 int main()
5 {
6 if(access("a.txt",R_OK) == 0) printf("可读\n");
7 if(access("a.txt",W_OK) == 0) printf("可写\n");
8 if(access("a.txt",X_OK) == 0) printf("可执行\n");
9 if(access("a.txt",F_OK) == 0) printf("存在\n");
10 }
-----------------------------------------------------------
chmod() - 改变文件/目录的权限
chmod("a.txt",0666);
truncate() ftruncate() - 指定文件的大小
remove() - 删除硬链接,硬链接到0 删除文件
rename() - 文件/目录 改名
umask() - 可以修改 创建文件时的权限屏蔽
umask() 设计方式比较典型,特点:先以新换旧,把旧的存起来,用完以后再以旧换新
文件读写 - open() read() write() close() lseek()
Today:
文件其他函数(非读写)
目录操作
文件的函数:dup(int oldfd); dup2(int oldfd,int newfd);
dup() 和 dup2() - 复制文件描述符,但不复制文件表
dup() 和 dup2()的区别: dup()新描述符由系统选择最小的可用值,而dup2()由程序员指定值,如果指定值被使用,强行关闭后使用。
-----------------------------------------------------------
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 int main()
6 {
7 int fd = open("a.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
8 if(fd == -1) perror("open"),exit(-1);
9 int fd2 = dup(fd);//复制描述符,不复制文件表
10 printf("fd=%d,fd2=%d\n",fd,fd2);
11 write(fd,"1",1);
12 write(fd2,"2",1);//如果覆盖 2个偏移量 2个文件表
13 int fd3 = dup2(fd,100);
14 printf("fd3=%d\n",fd3);
15 write(100,"ok",2);
16 int fd4 = open("b.txt",O_RDWR|O_CREAT,0666);//5
17 if(fd4 == -1) perror("open"),exit(-1);
18 int fd5 = dup2(fd,5);//强行关闭fd4
19 write(fd4,"HEHE",4);//写入a.txt,放在ok后面
20 close(fd);close(fd2);
21 }
运行后结果:
fd=3 fd2=4 fd3=100
a.txt = 12okHEHE
-----------------------------------------------------------
fcntl():
int fcntl(int fd,int cmd,...)
参数fd - 一个打开的文件描述符
参数cmd决定了功能:
F_DUPFD(long) 复制文件描述符,类似dup2(),区别:不强行关闭已经使用的描述符,而是取大于等于参数的可用描述符
F_GETFL/F_SETFL 获取/设置 文件描述符的状态,只能获取权限和状态标识,不能获取创建标识,设置时,只能设置O_APPEND
F_SETLK F_SETLKW F_GETLK 文件锁
经验: 与宏变量 做 位与运算 可以得到某一位/某几位,比如:取后8位二进制: & 0xFF
F_SETLK: 加文件锁,文件锁也是存于内存中的,文件锁可以锁定文件的某个部分而不锁定全部
F_SETLKW: 加文件锁,以阻塞方式加文件锁,如果锁不上,会等待,而F_SETLK直接返回错误
F_GETLK: 测试一把锁能否加上
使用文件锁需要结构 flock,成员:
struct flock
{
short l_type;//锁类型,有三种
short l_whence;//锁定起始点的参考位置
int l_start;//锁定起始点的偏移量
int l_len;//锁定的长度(字节数)
pid_t l_pid;//进程ID,GETLK使用,SETLK一般-1即可
};
l_type 包括:
F_RDLCK - 读锁
F_WRLCK - 写锁
F_UNLCK - 释放锁
读锁: 一种共享锁,允许读进程访问,锁定其它进程的写操作
写锁: 一种独占锁(互斥锁),不允许其它进程读写操作
释放锁: 解除之前的锁定,其它进程就可以继续操作。如果不释放锁,只能等到当前进程结束其它进程才能继续操作
l_whence 是锁定的起始点的参考位置,值为:
SEEK_SET SEEK_CUR SEEK_END
l_start 是起始点从参考位置的偏移量
l_whence 和 l_start 联合决定了起始点的位置,比如: l_whence = SEEK_SET l_start = 10,效果就是从头偏移10个做起始点
fcntl()加锁对 read() write()没有任何的约束力,锁定的是 其它进程的加锁行为。因此正确用法应该是:在进程中,读函数调用之前先加读锁,如果能加读锁再读;写函数调用之前先加写锁,如果能加写锁再写。
如果不能读/写直接返回,用F_SETLK;如果想等到能读/写位置,用F_SETLKW
如果读写之前加了锁,读写完成以后一定要释放锁。释放锁的方法:把锁的类型改为F_UNLCK,再调用fcntl()设置即可
文件的其它函数:
stat() / fstat() - 取硬盘文件/目录的各种状态,效果和ls -il 一样。stat()主要用于取文件的大小(不需要open)
C语言中如何描述时间:
1.秒差 time_t 其实就是个整数(当前时间-1970.01.01.00:00)
2.结构 struct tm 有年月日时分秒星期成员
计算机更喜欢time_t,人类看不懂秒差
需要转换函数:localtime()把秒差转结构
ctime() 可以把秒差转字符串(英文习惯)
-----------------------------------------------------------
access() - 判断文件的权限和是否存在
access("a.txt",宏)
R_OK W_OK X_OK - 权限判断
F_OK - 文件是否存在
返回0 代表存在 和 有权限
-------------------------------------
1 #include <stdio.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 int main()
5 {
6 if(access("a.txt",R_OK) == 0) printf("可读\n");
7 if(access("a.txt",W_OK) == 0) printf("可写\n");
8 if(access("a.txt",X_OK) == 0) printf("可执行\n");
9 if(access("a.txt",F_OK) == 0) printf("存在\n");
10 }
-----------------------------------------------------------
chmod() - 改变文件/目录的权限
chmod("a.txt",0666);
truncate() ftruncate() - 指定文件的大小
remove() - 删除硬链接,硬链接到0 删除文件
rename() - 文件/目录 改名
umask() - 可以修改 创建文件时的权限屏蔽
umask() 设计方式比较典型,特点:先以新换旧,把旧的存起来,用完以后再以旧换新