ICE实现的简单文件系统

我们的文件系统应用将实现一个简单的层次结构的文件系统,就像我们在 Windows UNIX 上所看到的文件系统。为了让例子代码的数量保持在可以管理的范围内,我们忽略了真实的文件系统的许多方面,比如所有权、权限、符号链接,以及其他一些特性。但我们所构建的功能足以告诉你,可以怎样实现一个功能完备的文件系统,而且我们还考虑了像性能和可伸缩性这样的问题。以这种方式,我们可以创建一个具有现实的复杂度的应用,而又不会被埋葬在大量代码中。


首先要说明的是,这个文件系统是非分布式的:尽管我们是在服务器中 实现这个应用,由客户对其进行访问 (所以我们可以从远地访问文件系统),应用的初始版本要求文件系统中的所有文件都由一个服务器提供。这就意味着,在文件系统的根之下的所有目录和文件都是在一个服务器上 实现的 (我们将在 XREF 中讨论怎样消除这个限制,创建真正的分布式文
件系统) 。

我们的文件系统由目录和文件组成。目录是可以容纳目录或文件的容器,也就是说,这个文件系统是层次结构的。在文件系统的根上有一个专用目录。每个目录和文件都有名字。其父目录相同的文件和目录必须具有不同的名字 (但父目录不同的文件和目录的名字可以相同)。换句话说,目录形成了命名范围,单个目录中的各个项的名字必须唯一。你可以列出目录的内容。目前,我们没有路径名的概念,也不能创建或销毁文件及目录。相反,服务器提供的是数目固定的目录和文件 (我们将在 XREF 中处理文件的创建和销毁)。你可以读写文件,但目前,读和写针对的总是文件的整个内容;你不可能读写文件的部分内容。

在给出了刚才概述的非常简单的需求之后,我们可以着手设计系统的接口了。文件和目录有共同之处:它们都有名字,而且文件和目录都可以包含在目录中。这提示我们,可以基类型来提供共有的功能,用派生类型来提供目录和文件专有的功能。

FileSyste.ice
module FileSystem{
	interface CAbsNode{//抽象的文件接口
		string GetName();//文件的名称
	};

	exception GenericError{//读写可能会抛出异常
		string sReson;
	};

	sequence<string> seqString;//文件内容
	interface CAbsFile extends CAbsNode{//可读可写的文件
		seqString Read();
		void Write(seqString text) throws GenericError;
	};

	sequence<CAbsNode*> seqNode;//复合节点:包含了分支结点【目录】和叶子结点
	interface CAbsFolder extends CAbsNode{//文件夹
		seqNode GetChilds();
	};
	
	interface CFileUtil{//获取文件系统的根目录
		CAbsFolder* GetRoot();
	};
};

FileImpl.h

#include <Ice/Ice.h>
#include "FileSystem.h"

namespace FileSystem{
	class CFile;
	typedef IceUtil::Handle<CFile> CFilePtr;
	class CFolder;
	typedef IceUtil::Handle<CFolder> CFolderPtr;
	class CNode : virtual public CAbsNode{//抽象文件结点
	public:
		static Ice::ObjectAdapterPtr  spObjAdapter;
	private:
		const std::string sName;//文件名
		CAbsFolderPtr spParentFolder;//文件所在目录【父目录】
	public:
		CNode(const std::string& name, const CFolderPtr& parent);
		virtual std::string GetName(const Ice::Current&);
	private:
		CNode(const CNode& other);//禁止拷贝构造
		void operator=(const CNode& other);//禁止赋值
	};
	

	class CFile : virtual public CAbsFile, virtual public FileSystem::CNode{//文件
	private:
		seqString vecString;//文件内容
	public:
		CFile(const std::string&, const CFolderPtr&);
		virtual FileSystem::seqString Read(const Ice::Current&);
		virtual void Write(const FileSystem::seqString&, const Ice::Current&);
	};

	class CFolder : virtual public CAbsFolder, virtual public FileSystem::CNode{//文件夹
	private:
		seqNode vecNode;//目录下包含的文件和文件夹
	public:
		CFolder(const std::string&, const CFolderPtr&);
		virtual FileSystem::seqNode GetChilds(const Ice::Current&);
		void AddChild(CAbsNodePrx child);
	};
}

FileImpl.cpp

#include "FileImpl.h"
#include <IceUtil/UUID.h>
#include <time.h>
using namespace std;

Ice::ObjectAdapterPtr FileSystem::CNode::spObjAdapter;
FileSystem::CNode::CNode(const string& name, const CFolderPtr& parent) 
	: sName(name), spParentFolder(parent){
		Ice::Identity oId; oId.name = (parent? IceUtil::generateUUID() : "RootDir");//创建一个标识
		CAbsNodePrx spNode = CAbsNodePrx::uncheckedCast(spObjAdapter->createProxy(oId));//创建结点
		if(parent){
			//CFolder* pFolder = dynamic_cast<CFolder*>(parent->GetSelf());
			parent->AddChild(spNode);//如果父目录不为空,则添加进去
		}
		spObjAdapter->add(this, oId);//同时添加到适配器中
}
std::string FileSystem::CNode::GetName(const Ice::Current&){ return sName;}

FileSystem::CFile::CFile(const string& name, const CFolderPtr& parent) : CNode(name, parent){}
FileSystem::seqString FileSystem::CFile::Read(const Ice::Current&){return vecString;}
void FileSystem::CFile::Write(const FileSystem::seqString& text, const Ice::Current&){vecString = text;}

FileSystem::CFolder::CFolder(const string& name, const CFolderPtr& parent) : CNode(name, parent){}
FileSystem::seqNode FileSystem::CFolder::GetChilds(const Ice::Current&){return vecNode;}
void FileSystem::CFolder::AddChild(const CAbsNodePrx child){vecNode.push_back(child);}

Server.cpp

#include "FileSystem.h"
#include "FileImpl.h"
#include <Ice/Application.h>
using namespace FileSystem;

using namespace std;

class CMyApp : virtual public Ice::Application{
public:
	virtual int run(int, char* []){
		//文件夹派生定义,文件基类定义
		CNode::spObjAdapter = communicator()->createObjectAdapterWithEndpoints("SimpleFilesystem", "default -p 10000");
		CFolderPtr spRootFolder = new CFolder("/", 0);//创建根目录

		CAbsFilePtr spTxtFile = new CFile("诗和远方", spRootFolder);//创建ReadMe.txt
		seqString vString; 
		vString.push_back("无迹方知流光逝,有梦不觉人生寒。");
		spTxtFile->Write(vString);

		CFolderPtr spPoetyFolder = new CFolder("诗仙李白", spRootFolder);

		CAbsFilePtr spDocFile = new CFile("静夜思", spPoetyFolder);
		vString.erase(vString.begin(), vString.end());
		vString.push_back("床前明月光,疑是地上霜。");
		vString.push_back("举头望明月,低头思故乡。");
		spDocFile->Write(vString);

		CNode::spObjAdapter->activate();
		communicator()->waitForShutdown();//等待我们发出“停止”命令
		if(interrupted())			cerr << appName() << ":接收到停止服务的信号,并成功停止了服务!" << endl;
		return 0;
	}
};

int main(int argc, char* argv[]){
	CMyApp theApp;
	return theApp.main(argc, argv);
}

Client.cpp

#include <Ice/Ice.h>
#include "FileSystem.h"
using namespace FileSystem;

#include <iostream>
#include <iterator>
using namespace std;


static void DirDisp(const CAbsFolderPrx& folder, int depth = 0)
{
	string sIndent(++depth, '\t');
	seqNode vecNode = folder->GetChilds();
	for(seqNode::const_iterator it = vecNode.begin(); it != vecNode.end(); it++){
		CAbsFolderPrx spFolder = CAbsFolderPrx::checkedCast(*it);
		CAbsFilePrx spFile = CAbsFilePrx::uncheckedCast(*it);
		cout << sIndent << (*it)->GetName() << (spFolder? " (Folder) : " : " (File) : ") << endl;
		if(spFolder)				DirDisp(spFolder);
		else{
			string sIndent(++depth, '\t');
			seqString vecString = spFile->Read();
			for(seqString::const_iterator it = vecString.begin(); it != vecString.end(); it++)		cout << sIndent << "\t" << *it << endl;
		}
	}
}

int main(int argc, char * argv[])
{
	int iStatus = 0;
	Ice::CommunicatorPtr spCommunicator;

	try {
		spCommunicator = Ice::initialize(argc, argv);//创建一个Communicator
		Ice::ObjectPrx spObjProxy = spCommunicator->stringToProxy("RootDir:default -p 10000");//创建一个根目录的代理
		if(!spObjProxy)				throw "Could not create proxy";
		CAbsFolderPrx spFolder = CAbsFolderPrx::checkedCast(spObjProxy);//向下映射
		if(!spFolder)							throw "Invalid proxy";

		cout << "Contents of root directory:" << endl;
		DirDisp(spFolder);
	}
	catch (const Ice::Exception & ex) {
		cerr << ex << endl;
		iStatus = 1;
	} 
	catch (const char * msg) {
		cerr << msg << endl;
		iStatus = 1;
	}

	if(spCommunicator)			spCommunicator->destroy();
	system("Pause");
	return iStatus;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值