/* 看例子,创建一个文件,在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;
}