c++删除已打开的文件

2 篇文章 0 订阅
2 篇文章 0 订阅
  • 情景

用fstream打开一个文件,在关闭之前,可以删除该文件和其所在的目录吗?

  • 结论

linux下,可以删除已打开文件和其所在目录,且对已存在的fstream读写操作无影响。但win下不行,有时notepad打开的文件可以删除,那是notepad会实时关闭文件。

  • 验证

我们实现一个类FileTest,该类有如下功能

  • 构造函数,分别以读写的方式打开该文件
  • 析构函数,关闭文件
  • Write函数,写文件
  • Read函数,读文件,读取Write写入的内容
  • RemovePath函数,删除文件
  • RemoveDir函数,删除文件所在目录
  • TestRemovePath函数,测试文件被打开时,能否删除文件,以及删除文件后Read还能不能读取到Read的内容
  • TestRW_AfterRmovePath函数,连续调用两次TestRemovePath
  • TestRemoveDir函数,测试文件被打开时,能否删除文件所在目录,以及删除目录后Read还能不能读取到Read的内容
#include<fstream>
#include <iostream>
#include<stdio.h>
#include<chrono>
#include<string>
#define log_debug(...) do{printf(__VA_ARGS__);printf("\n");}while(0)
class FileTest {
public:
	FileTest(const std::string &dir, const std::string &fname) :m_dir(dir), m_fpath(dir+fname) {
		m_ofs.open(m_fpath);
		m_ifs.open(m_fpath);
		if (!m_ofs || !m_ifs) {
			log_debug("FileTest::FileTest init fpath err,fpath=%s", m_fpath.c_str());
			m_is_valid = false;
		}
		else{
			log_debug("FileTest::FileTest init fpath okay,fpath=%s",m_fpath.c_str());
			m_is_valid = true;
		}
	}
	~FileTest() {
		m_ofs.close();
		m_ifs.close();
	}
	void Write() {
		if (!m_is_valid) return;
		if (m_ofs.bad())
			log_debug("FileTest::Write error,file is bad");
		auto before = m_ofs.tellp();
		m_ofs << m_test_str;
		m_ofs.flush();
		if ((m_ofs.tellp() - before) != m_test_str.size())
			log_debug("FileTest::Write wrong num,write=%d", m_ofs.tellp() - before);
		else
			log_debug("FileTest::Write okay");
	}
	void Read() {
		if (!m_is_valid) return;
		if (m_ifs.bad())
			log_debug("FileTest::Read error,file is bad");
		std::string str;
		str.resize(m_test_str.size());
		m_ifs.read(const_cast<char*>(str.data()),str.size());
		if (str != m_test_str)
			log_debug("FileTest::Read error,str error,str=%s", str.c_str());
		else
			log_debug("FileTest::Read okay");
	}
	void RemovePath() {
		if (!m_is_valid) return;
		if (std::remove(m_fpath.c_str()) != 0)
			log_debug("FileTest::RemoveFpath error");
		else
			log_debug("FileTest::RemoveFpath okay");
	}
	void RemoveDir() {
		if (!m_is_valid) return;
		if (std::remove(m_dir.c_str()) != 0)
			log_debug("FileTest::RemoveDir error");
		else
			log_debug("FileTest::RemoveDir okay");
	}
	void TestRemovePath() {
		Write();
		RemovePath();
		Read();
	}
	void TestRemoveDir() {
		Write();
		RemoveDir();
		Read();
	}
	void TestRW_AfterRmovePath() {
		TestRemovePath();
		TestRemovePath();
	}
	const std::string &Dir()const { return m_dir; }
	const std::string &Path()const { return m_fpath; }
private:
	std::string m_dir;
	std::string m_fpath;
	std::ofstream m_ofs;
	std::ifstream m_ifs;
	const std::string m_test_str = "hello";
	bool m_is_valid = true;
};
int main(int argc, char *argv[])
{
#ifdef WIN32
	FileTest ft("D:\\tmp\\test\\","a.txt");
#else
	FileTest ft("/root/test/", "a.txt");
#endif
	ft.TestRW_AfterRmovePath();
	ft.TestRemoveDir();
	return 0;
}

linux结果

root@VM-0-15-ubuntu:~# ./a.out
FileTest::FileTest init fpath okay,fpath=/root/test/a.txt
FileTest::Write okay
FileTest::RemoveFpath okay
FileTest::Read okay
FileTest::Write okay
FileTest::RemoveFpath error
FileTest::Read okay
FileTest::Write okay
FileTest::RemoveDir error
FileTest::Read okay

win结果

FileTest::FileTest init fpath okay,fpath=D:\tmp\test\a.txt
FileTest::Write okay
FileTest::RemoveFpath error
FileTest::Read okay
FileTest::Write okay
FileTest::RemoveFpath error
FileTest::Read okay
FileTest::Write okay
FileTest::RemoveDir error
FileTest::Read okay

std::remove

细心的读者发现,linux下没有成功删除目录,那是因为std::remove只能删除文件或空目录,非空目录不能删除。
下面是cppreference中,对std::remove的解释。
在这里插入图片描述
那么如果我们想要删除非空目录该怎么办呢?c++较高版本中提供了filesystem,提供如下两个api
std::filesystem::remove
std::filesystem::remove_all
其中remove_all可以删除非空目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值