/* 看例子,创建一个文件,在unlink,文件i节点的链接数变为0,但持有该文件的句柄,依然可以fgets和fputs该文件,说明文件的数据块依然存在,在fclose之后,才彻底删除,这就是使用临时文件的原理 */
#include<iostream> #include<memory.h> #include<stdio.h> #include<unistd.h> #include<sys/stat.h> /* setvbuf实现setbuf,仅供参考 */ void setbuf(FILE *fp, char *buf) { if ((NULL == buf) || (3 == fileno(fp))) { setvbuf(fp, NULL, _IONBF, 0); } else { if ((0 == fileno(fp)) || (1 == fileno(fp))) { setvbuf(fp, buf, _IOLBF, BUFSIZ); } else { setvbuf(fp, buf, _IOFBF, BUFSIZ); } } } int main(int argc, char *argv[]) { FILE *file; struct stat buf; char str[1024] = {0}; file = fopen(argv[1], "w+"); if (EOF == fputs("adfadsf\n", file)) { std::cout<<"puts error"<<std::endl; } fstat(fileno(file), &buf); std::cout<<"nlink:"<<buf.st_nlink<<std::endl; unlink(argv[1]);//这里unlink之后,后边fputs和fgets还可以操作,说明文件数据块未删除 memset(&buf, 0, sizeof(struct stat)); fstat(fileno(file), &buf); std::cout<<"nlink:"<<buf.st_nlink<<std::endl; if (access(argv[1], F_OK) < 0) { std::cout<<"not exist!"<<std::endl; } fflush(file); rewind(file); //这不比较关键,因为打开文件是+追加方式,所以默认文件当前位置是在文件末尾 //fclose(file); //file = fopen(argv[1], "rw"); if (NULL == fgets(str, 1024, file)) { std::cout<<"gets error!"<<std::endl; } getchar(); std::cout<<"str:"<<str<<std::endl; fclose(file); } /* 再看一个例子 */ #include<iostream> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> int main(int argc, char *argv[]) { if (argc != 2) { std::cout<<"param error"<<std::endl; return -1; } int fd = open(argv[1], O_RDWR|O_CREAT, S_IREAD|S_IWRITE); if (-1 == fd) { return -1; } if (unlink(argv[1]) < 0) { return -1; } /*此处写大量数据到文件*/ sleep(15);//在这段时间内,查看系统占用磁盘大小,是有增加的 std::cout<<"done!"<<std::endl; return 0; //退出后,磁盘大小恢复,说明已经删除了文件存储的数据部分 } unlink的这种用法,即使在程序崩溃时(崩溃后,相当于文件关闭),所创建的临时文件也不会遗留下来,即在创建后,立即unlink,虽然文件i节点链接数等于0,但因为文件仍是打开的,所以对其读写仍然有效 /* 临时文件举例 */ #include<iostream> #include<sys/stat.h> #include<sys/types.h> #include<stdio.h> int main(int argc, char *argv[]) { FILE *file = tmpfile(); struct stat buf; fstat(fileno(file), &buf); std::cout<<"tmp file st_nlink:"<<buf.st_nlink<<std::endl; //这里显示文件i节点的链接数等于0 return 0; }