在应用开发中,我们经常会把一些字符串,或一些结构体保存到文件中,保存到文件的方法一般都是先打开文件,然后将内容写入,最后再将文件关闭,这是不可避免的,相比C#中的File.ReadAllText,WriteAllText,ReadAllBuffer,WriteAllBuffer实在是麻烦不少,既然经常有这样的需求,我们可以将它们写成一个函数,能比较方便的调用而且在以后的项目中复用,代码如下:
//ZFile.hpp
#pragma once #include <string> #include <vector> #include <fstream> /*! * 文件操作模版类 * */ template <class tchar> class ZFileT { public: typedef std::basic_string<tchar, std::char_traits<tchar>, std::allocator<tchar> > this_string; typedef std::basic_istringstream<tchar, std::char_traits<tchar>, std::allocator<tchar> > this_istringstream; public: /*! * 读取文件缓冲区数据 * * \param path 文件路径 * \param context 内容 * \return 成功返回true,否则返回false。 */ static bool Read(const this_string &path, std::vector<char> &context) { std::ifstream ifs; ifs.open(path, std::ios::binary); if (!ifs.is_open()) return false; //获取文件大小 auto pos = ifs.tellg(); ifs.seekg(0, std::ios::end); auto size = ifs.tellg(); ifs.seekg(pos); //读取全部 context.resize((size_t)size); ifs.read(context.data(), size); ifs.close(); return ifs.good(); } /** * 将缓冲区的数据写入文件 * * \param path 文件路径 * \param buffer 缓冲区 * \param size 字节数 * \return 成功返回true,否则返回false * \note 如果文件已经存在,之前的内容都将被清除,如果内容不存在,则创建新的文件 */ static bool Write(const this_string &path, const void *buffer, size_t size) { std::ofstream ofs; ofs.open(path, std::ios::binary); if (!ofs.is_open()) return false; //写入缓冲区数据到文件 ofs.write((const char *)buffer, size); ofs.close(); return ofs.good(); } /*! * 读取文件所有文本内容 * * \param path 文件路径 * \param text 字符串引用 * \return 如果成功返回true,否则返回false。 */ static bool ReadAllText(const this_string &path, std::string &text) { std::ifstream ifs(path); if (!ifs.is_open()) return false; //读取文件 std::istreambuf_iterator<char>beg(ifs), end; text.assign(beg, end); ifs.close(); return ifs.good(); } /*! * 写入所有文本 * * \param path 文件路径 * \param text 字符内容 * \return 如果成功返回true,否则返回false。 */ static bool WriteAllText(const this_string &path, const std::string &text) { std::ofstream ofs(path); if (!ofs.is_open()) return false; //内容流入文件 ofs << text; ofs.close(); return ofs.good(); } /*! * 读取所有行 * * \param path 文件路径 * \param lines 行容器 * \return 如果成功返回true,否则返回false。 */ static bool ReadAllLines(const this_string &path, std::vector<std::string> &lines) { std::ifstream ifs(path); if (!ifs.is_open()) return false; //读取到并放到容器中 std::string line; while (!ifs.eof() && !ifs.bad()) { getline(ifs, line); lines.push_back(line); } ifs.close(); return !ifs.bad(); //此处不能使用ifs.good(),ifs.eof()为true时此函数返回false } }; typedef ZFileT<char> ZFileA; typedef ZFileT<wchar_t> ZFileW; #ifdef UNICODE typedef ZFileW ZFile; #else typedef ZFileA ZFile; #endif // UNICODE
测试用例
/***** File *****/ namespace ZFileTest { //缓冲区写入文件 TEST(ZFile, WriteAndRead) { const wchar_t *pszFilePath = L"temp.txt"; std::vector<char> write; write.push_back('A'); write.push_back('B'); write.push_back('\r'); write.push_back('\n'); write.push_back('C'); EXPECT_TRUE(ZFile::Write(pszFilePath, write.data(), write.size())); std::vector<char> read; EXPECT_TRUE(ZFile::Read(pszFilePath, read)); EXPECT_EQ(write.size(), read.size()); for (size_t i = 0; i < write.size(); ++i) { EXPECT_EQ(write[i], read[i]); } } //写读文件内容 TEST(ZFile, WriteAllTextAndReadAllText) { const wchar_t *pszFilePath = L"temp.txt"; std::string strWrite = "今天没有作业"; std::string strRead; EXPECT_TRUE(ZFile::WriteAllText(pszFilePath, strWrite.c_str())); EXPECT_TRUE(ZFile::ReadAllText(pszFilePath, strRead)); EXPECT_EQ(strWrite, strRead); } //读取文件所有行 TEST(ZFile, ReadAllLines) { //不存在时 { auto strFileNameNotExist = ZPath::GetCurrentPath() + (L"\\lines_not_exist.txt"); std::vector<std::string> lines; EXPECT_FALSE(ZFile::ReadAllLines(strFileNameNotExist, lines)); } auto strFileName = ZPath::GetCurrentPath() + (L"\\lines.txt"); std::vector<std::string> lines; EXPECT_TRUE(ZFile::ReadAllLines(strFileName, lines)); EXPECT_EQ(lines.size(), 3); EXPECT_EQ(lines[0], "line0"); EXPECT_EQ(lines[1], "line1"); EXPECT_EQ(lines[2], "line2"); } }
像这样子,任何地方需要读写文本文件所有内容时只需要ZFile::ReadAllText/ZFile::WriteAllText,从而也再不需要每次都打开关闭了,确实方便了不少。
本站部分资源收集于网络,纯个人收藏,无商业用途,如有侵权请及时告知!