我需要实现一个包含常规文本文件的类,该文件对多个线程(例如“读者”线程和“编写器”)的读写操作都有效。
我正在使用visual studio 2010并且只能使用它(VS 2010)拥有的可用库,因此我选择使用std::fstream
类进行文件操作以及CreateThread
函数和放大器;标题中的CRITICAL_SECTION
对象。
我可以先说,我在一开始就寻求一个简单的解决方案 - 只是这样才有效......:)
我的想法如下:
我创建了一个File类,它将文件和“mutex”(CRITICAL_SECTION
对象)保存为私有成员。
此外,此类(File类)为“读取器/写入器”线程提供“公共接口”,以便对读取和写入操作执行文件的同步访问。
请参阅File类的头文件:
class File {
private:
std::fstream iofile;
int size;
CRITICAL_SECTION critical;
public:
File(std::string fileName = " ");
~File();
int getSize();
// the public interface:
void read();
void write(std::string str);
};
另见源文件:
#include "File.h"
File :: File(std::string fileName)
{
// create & open file for read write and append
// and write the first line of the file
iofile.open(fileName, std::fstream::in | std::fstream::out | std::fstream::app); // **1)**
if(!iofile.is_open()) {
std::cout << "fileName: " << fileName << " failed to open! " << std::endl;
}
// initialize class member variables
this->size = 0;
InitializeCriticalSection(&critical);
}
File :: ~File()
{
DeleteCriticalSection(&critical);
iofile.close(); // **2)**
}
void File :: read()
{
// lock "mutex" and move the file pointer to beginning of file
EnterCriticalSection(&critical);
iofile.seekg(0, std::ios::beg);
// read it line by line
while (iofile)
{
std::string str;
getline(iofile, str);
std::cout << str << std::endl;
}
// unlock mutex
LeaveCriticalSection(&critical);
// move the file pointer back to the beginning of file
iofile.seekg(0, std::ios::beg); // **3)**
}
void File :: write(std::string str)
{
// lock "mutex"
EnterCriticalSection(&critical);
// move the file pointer to the end of file
// and write the string str into the end of the file
iofile.seekg(0, std::ios::end); // **4)**
iofile << str;
// unlock mutex
LeaveCriticalSection(&critical);
}
所以我的问题是(参见代码中有关问题的数字):
1)我是否需要为我希望执行的读写操作指定其他内容?
2)我需要在破坏者中添加其他任何东西吗?
3)我需要在这里添加什么才能从文件的开头一定发生每次读取操作?
4)我需要在这里修改/添加什么,以便每次写入都发生在文件的末尾(意味着我希望将str
字符串附加到文件的末尾)?
5)任何进一步的评论都会很棒:另一种实施方式,优点和进展关于我的实施,要注意等等的缺点'.....
提前致谢,
盖。
答案 0 :(得分:1)
fstream
,对象在它的析构函数中自己处理。ios::app
打开文件,这会导致每个写入操作追加到末尾(包括忽略设置写入位置的搜索操作IIRC)。有一堆不会像你想要的那样工作......
iofile
,对吗?您正在受互斥保护的边界之外访问它... read()
不会返回任何数据,它应该做什么?clear()
。BTW:这看起来像是日志代码或文件支持的消息队列。两者都可以以线程友好的方式创建,但为了提出建议,您必须告诉我们您实际上要做什么。这也是你应该在课堂上放置评论部分的内容,这样任何读者都可以理解这个意图(现在更重要的是,你要记住它应该是什么)。