1.文件描述符
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //查看输入,输出,出错的文件描述符
6 printf("stdin 的文件描述符是:%d\n",stdin->_fileno);
7 printf("stdout 的文件描述符是:%d\n",stdout->_fileno);
8 printf("stderr 的文件描述符是:%d\n",stderr->_fileno);
9 return 0;
10 }
11
2.open的使用
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7 //只写方式打开文件,如果不存在则创建
8 if((fd = open("./test.txt",O_WRONLY | O_CREAT)) == -1){
9 perror("open error");
10 return -1;
11 }
12 close(fd);
13 puts("open seccess");
14
15 return 0;
16 }
17
18
3.O_EXCL创建文件
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7 //判断错误原因
8 //只读方式打开文件,如果不存在就创建,如果存在将EEXIST置位错误码
9 if((fd = open("./test.txt",O_RDONLY | O_CREAT | O_EXCL,0664)) == -1){
10 if(errno == EEXIST){
11 puts("文件已经存在,无法重复创建");
12 return -1;
13 }else{
14 perror("open error");
15 return -1;
16 }
17 }
18 puts("open success");
19 return 0;
20 }
21
22
4.close的使用
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7 //判断错误原因
8 //只读方式打开文件,如果不存在就创建,如果存在将EEXIST置位错误码
9 if((fd = open("./test1.txt",O_RDONLY | O_CREAT | O_EXCL,0664)) == -1){
10 if(errno == EEXIST){
11 puts("文件已经存在,无法重复创建");
12 return -1;
13 }else{
14 perror("open error");
15 return -1;
16 }
17 }
18 puts("open success");
19
20 //关闭文件
21 if(close(fd) == -1){
22 puts("文件关闭失败");
23 }else{
24 puts("close success");
25 }
26 return 0;
27 }
28
29
5.write&read的使用
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7 //以只写的方式打开文件,如果不存在则创建,如果存在则清空
8 if((fd = open("./test.txt",O_WRONLY | O_CREAT | O_TRUNC ,0664)) == -1){
9 perror("WRONLY open error");
10 return -1;
11 }
12
13 //输出文件描述符
14 printf("fd = %d\n",fd);
15
16 //定义容器存放数据
17 char str[] = "hello , long time no see\n";
18
19 //将数据写入文件中
20 write(fd,str,sizeof(str));
21
22 //关闭文件
23 close(fd);
24
25 //重新以只读的方式打开文件
26 if((fd = open("./test.txt",O_RDONLY)) == -1){
27 perror("RDONLY open error");
28 return -1;
29 }
30
31 //定义容器从文件读取中32字节的数据
32 char ch[32] = "";
33 int ret = read(fd,ch,sizeof(ch));
34
35 //将数据写入标准输出文件描述符中
36 write(1,ch,ret);
37
38 //关闭文件
39 close(fd);
40
41 return 0;
42 }
43
44
6.使用write&read完成两个文件的拷贝
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //判断传入文件个数
6 if(argc != 3){
7 puts("input error");
8 puts("usage: ./a.out srcfile destfile");
9 return -1;
10 }
11
12 //定义两个文件描述符
13 int fdsrc = 0;
14 int fddest = 0;
15
16 //以只读的方式打开源文件
17 if((fdsrc = open(argv[1],O_RDONLY)) == -1){
18 perror("src open error");
19 return -1;
20 }
21
22 //以只写的方式打开目标文件,如果不存在则创建,如果存在则清空
23 if((fddest = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC,0664)) == -1){
24 perror("dest open error");
25 return -1;
26 }
27
28 //定义容器搬运数据
29 //记录每次搬运的个数的变量
30 char buf[32];
31 int ret = 0;
32
33 //循环将读到的数据写入到文件
34 while((ret = read(fdsrc,buf,sizeof(buf))) > 0){
35 write(fddest,buf,ret);
36 write(1,buf,ret); //输出看一下内容
37 }
38
39 //关闭文件
40 close(fdsrc);
41 close(fddest);
42
43 //拷贝成功
44 puts("copy success");
45
46 return 0;
47 }
48
49
7.lseek的使用
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7
8 //只读方式打开文件
9 if((fd = open("./test.txt",O_RDONLY)) == -1){
10 perror("open error");
11 return -1;
12 }
13
14 //输出文件大小
15 printf("size = %ld\n",lseek(fd,0,SEEK_END));
16
17 //关闭文件
18 close(fd);
19
20 return 0;
21 }
22
23
8.lseek对图片的数据读写
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd = 0;
7
8 //只读方式打开文件
9 if((fd = open("./Mofs.bmp",O_RDONLY)) == -1){
10 perror("open error");
11 return -1;
12 }
13
14 //输出文件大小
15 printf("size = %ld\n",lseek(fd,0,SEEK_END));
16
17 //将光标从开头位置向后偏移2字节后得到文件头的文件大小部分
18 lseek(fd,2,SEEK_SET);
19
20 //读取出文件的大小
21 int ret = 0;
22 read(fd, &ret, sizeof(ret));
23
24 //将图片的大小输出
25 printf("size = %d\n",ret);
26
27 //关闭文件
28 close(fd);
29
30 return 0;
31 }
32
9.关于文件描述符的拷贝问题
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd1 = 0;
7
8 //读写的方式打开文件,如果不存在,则创建,如果存在,则清空
9 if((fd1 = open("./test.txt",O_RDWR | O_CREAT | O_TRUNC,0664)) == -1){
10 perror("open error");
11 return -1;
12 }
13
14 //输出文件描述符的值
15 printf("fd1 = %d\n",fd1);
16
17 //将文件描述符直接拷贝
18 int fd2 = fd1;
19
20 //通过fd1向文件中写入数据
21 write(fd1,"hello world",strlen("hello world"));
22
23 //定义一个容器存放使用fd2读取的数据,如果能读取数来数据,说明不共享光标
24 //如果不能读取出来数据,则说明共享光标
25 char buf [16] = "";
26 read(fd2,buf,sizeof(buf));
27
28 //将数据写入终端
29 write(1,buf,sizeof(buf));
30
31 //关闭文件
32 if(close(fd1) != 0){
33 perror("close fd1 error");
34 return -1;
35 }
36
37 //判断关闭第二个文件描述符是否会出错
38 if(close(fd2) != 0){
39 perror("close fd2 error");
40 return -1;
41 }
42
43 return 0;
44 }
45
46
10.使用dup函数进行文件描述符的拷贝
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义文件描述符
6 int fd1 = 0;
7
8 //使用只读的方式打开fd1
9 if((fd1 = open("./test.txt",O_RDONLY)) == -1){
10 perror("open error");
11 return -1;
12 }
13
14 //调用文件描述符拷贝函数dup
15 int fd2 = dup(fd1);
16
17 //通过fd1将光标移动到第6个字节处
18 lseek(fd1,6,SEEK_SET);
19
20 //关闭文件描述符
21 close(fd1);
22
23 //使用fd2从文件中读取数据,如果读取的数据是hello说明不共享光标
24 //如果读到的是world说明共享同一光标
25 char buf[5];
26 int ret = read(fd2,buf,sizeof(buf));
27
28 //将数据写入标准输出中
29 write(1,buf,ret);
30 puts("");
31
32 //判断关闭指针
33 if(close(fd2) != 0){
34 perror("close fd2 error");
35 return -1;
36 }
37
38 return 0;
39 }
40
11.多次使用open打开同一个文件,每次使用open函数,都会产生一个新的文件描述符,记录同一个文件的文件描述符没有关系,也不共享同一个光标
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义两个文件描述符
6 int fd1 = 0;
7 int fd2 = 0;
8
9 //以只读的方式打开一个文件 两次
10 if((fd1 = open("./test.txt",O_RDONLY)) == -1){
11 perror("fd1 open error");
12 return -1;
13 }
14 if((fd2 = open("./test.txt",O_RDONLY)) == -1){
15 perror("fd2 open error");
16 return -1;
17 }
18
19 //输出文件描述符
20 printf("fd1 = %d\n",fd1);
21 printf("fd2 = %d\n",fd2);
22
23 //将fd1的光标进行偏移
24 lseek(fd1,6,SEEK_SET);
25
26 //从fd2中读取数据,如果读取的是hello,说明不共享光标
27 //如果读到的是world,说明共享光标
28 char buf[5] = "";
29 int ret = read(fd2,buf,sizeof(buf));
30
31 //将数据输出
32 write(1,buf,ret);
33
34 //关闭文件
35 close(fd1);
36 close(fd2);
37
38 return 0;
39 }
40
41
12.使用dup2函数完成文件描述符的拷贝
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //定义两个文件描述符
6 int fd1 = 0;
7 int fd2 = 0;
8
9 //让两个文件描述符分别以只读,读写的方式打开不同的文件
10 if((fd1 = open("./1.c",O_RDONLY)) == -1){
11 perror("fd1 open error");
12 return -1;
13 }
14 if((fd2 = open("./test.txt",O_RDWR)) == -1){
15 perror("fd2 open error");
16 return -1;
17 }
18 /*
19 printf("fd1 = %d\n",fd1);
20 printf("fd2 = %d\n",fd2);
21 //调用文件描述符拷贝函数
22 //操作结束后,fd1和fd2都指向fd2原本指向的文件
23 dup2(fd2,fd1);
24
25 //输出文件描述符的大小
26 printf("fd1 = %d\n",fd1);
27 printf("fd2 = %d\n",fd2);
28
29 //将fd1从起始位置偏移6字节
30 lseek(fd1,6,SEEK_SET);
31
32 //通过fd2进行读取数据,如果读取的结果为hello则说明不共享光标
33 //如果读取到的结果为wrold,则说明共享光标
34 char buf[5] = "";
35 int ret = read(fd2,buf,sizeof(buf));
36
37 //将读取的数据展示到终端上
38 write(1,buf,ret);
39 */
40 //常用的操作
41 dup2(fd2,1);
42
43 //将stdout的文件描述符先关闭,并将1号文件描述符的功能更改为fd2,
44 //所有的对标准输出进行的操作都是对文件的操作
45 //该文件也被成为日志文件
46 printf("hello呀,");
47 puts("long time no see, are you OK?");
48
49 //关闭文件
50 close(fd1);
51 close(fd2);
52
53 return 0;
54 }
55
13.文件状态函数stat
1 #include
2
3 int main(int argc, const char *argv[])
4 {
5 //文件状态的变量
6 struct stat sb;
7
8 //调用文件状态函数,获取文件的状态
9 stat("./test.txt",&sb);
10
11 //输出文件的iNode号
12 printf("inode: %ld\n",sb.st_ino);
13
14 //文件的类型
15 printf("type: %#o\n",sb.st_mode & S_IFMT);
16
17 //文件的权限
18 printf("mode: %#o\n",sb.st_mode & 0777);
19
20 //文件的大小
21 printf("size: %ld\n",sb.st_size);
22
23 //文件的硬链接数
24 printf("nlink: %ld\n",sb.st_nlink);
25
26 //最后一次修改时间
27
28 struct tm *t = localtime(&(sb.st_mtime));
29 printf("last modified time: %4d-%02d-%02d %02d:%02d:%02d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
30
31 return 0;
32 }
33