// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <mutex>
#include <map>
#include <string>
#include <filesystem>
//文件管理单例类
class ManagerFile
{
public:
static ManagerFile& getInstance()
{
static std::once_flag s_flag;
std::call_once(s_flag, [&]() {
instance_.reset(new ManagerFile());
});
return *instance_;
}
//
//************************************
// FullName: ManagerFile::init
// Access: public
// @Parameter: std::string name 文件名
// @Parameter: size_t fileMaxSize 文件大小限制
// @Returns: void
// @author: 君莫笑
// @date: 2021/10/26 15:07
// @bref: 初始化
//************************************
void init(std::string name, size_t fileMaxSize);
//************************************
// FullName: ManagerFile::writeFile
// Access: public
// @Parameter: std::string name 文件名
// @Parameter: const char * fp 写入文件的内容
// @Parameter: const int len 写入数据长度
// @Returns: void
// @author: 君莫笑
// @date: 2021/10/26 15:08
// @bref: 写入数据
//************************************
void writeFile(std::string name, const char* fp, const int len);
//************************************
// FullName: ManagerFile::removeFile
// Access: public
// @Parameter: std::string name 文件名
// @Returns: bool
// @author: 君莫笑
// @date: 2021/10/26 15:09
// @bref: 删除文件
//************************************
bool removeFile(std::string name);
private:
ManagerFile() = default;
//防止拷贝构造
ManagerFile& operator=(const ManagerFile&) = delete;
ManagerFile(const ManagerFile& data) = delete;
static std::unique_ptr<ManagerFile> instance_;
private:
std::map<std::string, std::shared_ptr<std::ofstream>> m_foutMap;
std::map<std::string, size_t> m_currentFileSizeMap;
size_t m_iFileMaxSize{ 0 };
size_t m_iWriteFileMode{ 0 };
std::mutex m_fileOpt_mx;
};
std::unique_ptr<ManagerFile> ManagerFile::instance_;
void ManagerFile::init(std::string name, size_t fileMaxSize)
{
std::lock_guard<std::mutex> lck(m_fileOpt_mx);
m_iFileMaxSize = fileMaxSize;
auto itemPos = m_foutMap.find(name);
if (itemPos != m_foutMap.end())
{
if (!itemPos->second)
{
itemPos->second.reset(new std::ofstream());
}
}
else
{
m_foutMap[name].reset(new std::ofstream());
}
if (m_foutMap[name])
{
std::string strFileName = makeFilePathName(name);
if (!strFileName.empty())
{
m_foutMap[name]->open(strFileName, std::ios::binary | std::ios::out | std::ios::trunc);
m_currentFileSizeMap[name] = 0;
}
}
}
void ManagerFile::writeFile(std::string name, const char* fp, const int len)
{
std::lock_guard<std::mutex> lck(m_fileOpt_mx);
auto itemPos = m_foutMap.find(name);
if (itemPos == m_foutMap.end())
{
return;
}
if (!itemPos->second)
{
return;
}
int iCurrFileSize = 0;
auto itr = m_currentFileSizeMap.find(name);
if (itr == m_currentFileSizeMap.end())
{
return;
}
iCurrFileSize = itr->second;
std::string strFileName = makeFilePathName(name);
if (iCurrFileSize < m_iFileMaxSize)
{
itemPos->second->write(fp, len);
itemPos->second->flush();
std::filesystem::path p(strFileName);
itr->second = std::filesystem::file_size(p);
}
else
{
itemPos->second->flush();
itemPos->second->close();
itr->second = 0;
if (!strFileName.empty())
{
itemPos->second->open(strFileName, std::ios::binary | std::ios::out | std::ios::trunc);
}
}
}
bool ManagerFile::removeFile(std::string name)
{
std::lock_guard<std::mutex> lck(m_fileOpt_mx);
auto itemPos = m_foutMap.find(name);
if (itemPos == m_foutMap.end())
{
return false;
}
if (!itemPos->second)
{
return false;
}
if (itemPos->second->is_open())
{
itemPos->second->flush();
itemPos->second->close();
}
bool bl = false;
std::string strFileName = makeFilePathName(name);
if (!strFileName.empty())
{
std::ifstream fileTemp(strFileName.c_str());
itemPos->second->open(strFileName, std::ios::binary | std::ios::out | std::ios::trunc); //清空文件内容
itemPos->second->flush();
itemPos->second->close();
std::this_thread::sleep_for(std::chrono::milliseconds(100)); //必须要等待,否则可能会删除文件失败
bool bl = remove(strFileName.c_str());
}
if (itemPos->second && itemPos->second->is_open())
{
itemPos->second->close();
itemPos->second = nullptr;
}
m_foutMap.erase(itemPos);
return bl;
}
std::string ManagerFile::makeFilePathName(std::string& name)
{
std::filesystem::path pDir= std::filesystem::current_path();
std::string fileName = pDir.string();
fileName += "\\";
fileName += name;
return fileName;
}
int main()
{
//使用实例
std::string strFileName = "123.txt";
std::string strData = "test file 12345678";
size_t iFileSize = 1024;
ManagerFile::getInstance().init("123.txt", iFileSize);
ManagerFile::getInstance().writeFile("123.txt", strData.c_str(), strData.length());
return 0;
}
|