C#实现的内存分页机制的一个实例
//多页索引表管理类(全局主索引表管理类)
public class MuliPageIndexFeatureClass : IDisposable
{
protected List<IndexPageClass> MuliPageIndexTable = new List<IndexPageClass>(); //多页索引表对象
//
protected int CurrentMemoryPageIndex = -1; //当前内存索引页(已载入内存的索引页的对象)
public int PerPageDwCount = 30000; //每页地物个数 default=3,0000 /// <summary>
/// = Application.StartupPath + "\\tempfiles\\tmp_vct";
/// </summary>
protected string tmpDir = Application.StartupPath + "\\tempfiles\\tmp_vct"; public MuliPageIndexFeatureClass()
{
this.MemoryPageList.Clear();
//txt存放目录
string dir = this.tmpDir;
if (System.IO.Directory.Exists(dir) == true)
{
try
{
System.IO.Directory.Delete(dir, true);
}
catch { }
}
if(System.IO.Directory.Exists(dir) == false)
{
System.IO.Directory.CreateDirectory(dir);
}
} //创建多页索引表(建立多页索引表) 派生类需重写
private IndexPageClass tmpIP = null;
public virtual bool CreateMuliPageIndexTable(FeatureOIDMap pfeat)
{
//txt存放目录
string dir = this.tmpDir;
if (System.IO.Directory.Exists(dir) == false)
{
System.IO.Directory.CreateDirectory(dir);
}
//创建多页索引表....
if (this.tmpIP == null)
{ //产生一个新的索引页面
this.tmpIP = new IndexPageClass();
tmpIP.RelationFileName = "vctline" + this.MuliPageIndexTable.Count.ToString() + ".txt";
tmpIP.CreatedIndex = false;
tmpIP.OpenTxt();
this.MuliPageIndexTable.Add(tmpIP);
}
else
{
if (tmpIP.dt.Count >=this.PerPageDwCount)
{ //保存原有的索引页面
tmpIP.SaveToTxt();
tmpIP.CloseTxt();
tmpIP.CreatedIndex = true;
tmpIP.dt.Clear();
//产生一个新的索引页面
tmpIP = new IndexPageClass();
tmpIP.RelationFileName = "vctline" + this.MuliPageIndexTable.Count.ToString() + ".txt";
tmpIP.CreatedIndex = false;
tmpIP.OpenTxt();
this.MuliPageIndexTable.Add(tmpIP);
}
}
if(tmpIP!=null)
{
tmpIP.dt.Add(pfeat.ObjectID,pfeat);
if (tmpIP.dt.Count % 100==0)
{
Application.DoEvents();
}
}
return true;
}
public virtual bool SaveEndPageIndexTable()
{
bool rbc = false;
if (tmpIP != null)
{
tmpIP.SaveToTxt();
tmpIP.CloseTxt();
tmpIP.CreatedIndex = true;
tmpIP.dt.Clear();
tmpIP.Dispose();
tmpIP = null;
rbc = true;
}
return rbc;
} //选择记录集 OK
private List<int> MemoryPageList = new List<int>();
private int MemoryPagesOnLine = 7; //在线的内存索引文件数
public FeatureOIDMap GetLine(int bsm)
{
FeatureOIDMap feat = null;
bool IsSearch = true; //是否要进行分页搜索操作标志 默认为是 if (this.CurrentMemoryPageIndex != -1)
{ //当前内存分页中是否有dwID地物唯一编号
if (this.MuliPageIndexTable[this.CurrentMemoryPageIndex].DwidList.Contains(bsm) == true)
{
IsSearch = false;
}
} if (IsSearch == true)
{ //进行分页搜索操作 并置为当前内存分页
for (int i = 0; i < this.MuliPageIndexTable.Count; i++)
{
if (this.MuliPageIndexTable[i].DwidList.Contains(bsm) == true)
{
if (this.CurrentMemoryPageIndex != i)
{
//需搜索页面不在当前内存页面中 (需置换页面)
if (this.CurrentMemoryPageIndex != -1)
{
//修正在线内存索引文件个数
if (this.MemoryPageList.Contains(i) == false)
{
this.MemoryPageList.Add(i);
}
if (this.MemoryPageList.Contains(this.CurrentMemoryPageIndex) == false)
{
this.MemoryPageList.Add(this.CurrentMemoryPageIndex);
}
if (this.MemoryPageList.Count > this.MemoryPagesOnLine)
{
this.MemoryPageList.RemoveAt(0);
}
//清除离线内存索引文件中坐标大数据 for (int k = 0; k < this.MuliPageIndexTable.Count; k++)
{
if (this.MemoryPageList.Contains(k) == false)
{
this.MuliPageIndexTable[k].Dispose();
}
}
}
if (this.MuliPageIndexTable[i].dt.Count <= 0)
{
this.MuliPageIndexTable[i].ReadFromTxt(); //从txt文件中读取记录
}
this.CurrentMemoryPageIndex = i;
break;
}
} //end if
} //end for
} //当前分面页页进行搜索...
if (this.CurrentMemoryPageIndex != -1)
{
feat = this.MuliPageIndexTable[this.CurrentMemoryPageIndex].GetLine(bsm);
}
return feat;
} //获取一页索引表
public IndexPageClass GetIndexPageClass(int index)
{
if (MuliPageIndexTable != null && this.MuliPageIndexTable.Count > index)
{
return this.MuliPageIndexTable[index];
}
return null;
} public void Clear()
{
this.Dispose();
}
#region IDisposable 成员 public void Dispose()
{
if (this.MuliPageIndexTable.Count > 0)
{
for (int i = 0; i < this.MuliPageIndexTable.Count; i++)
{
this.MuliPageIndexTable[i].Dispose();
}
}
this.MuliPageIndexTable.Clear();
this.CurrentMemoryPageIndex = -1;
} public void DeleteTempFile()
{
//分页对应的txt文件...
string dir = this.tmpDir;
if (System.IO.Directory.Exists(dir) == true)
{
try
{
System.IO.Directory.Delete(dir, true);
}
catch
{
}
}
} #endregion
}
//一页内索引表管理类
public class IndexPageClass : IDisposable
{
public bool CreatedIndex = false;
public List<int> DwidList = new List<int>(); //地物唯一编号的集合
public string RelationFileDir = Application.StartupPath + "\\tempfiles\\tmp_vct";
//相关的txt文件 dltb_xzdw_Relation_1.txt
public string RelationFileName = "";
//排序后的记录关系记录DataRow集合 //从_1.txt从读取内容
protected FeatureOIDMapCollection m_dt = new FeatureOIDMapCollection();
protected System.IO.StreamWriter sw = null;
private int m_index = 0; //get dt
public FeatureOIDMapCollection dt
{
get
{
return m_dt;
}
} /// <summary>
/// //打开文本分页文件写入流
/// </summary>
public bool OpenTxt()
{
string relfilename = this.RelationFileDir + "\\" + this.RelationFileName;
if (System.IO.File.Exists(relfilename) == true)
{
System.IO.File.Delete(relfilename);
}
this.sw = new StreamWriter(relfilename, true, Encoding.Default);
return true;
} /// <summary>
/// 向写入流写入一行记录
/// </summary>
private bool AppentLine(string pLine)
{
if (this.sw != null)
{
this.sw.WriteLine(pLine);
this.m_index += 1; if (this.m_index % 10000 == 0)
{
this.sw.Flush();
Application.DoEvents();
}
}
return true;
}
/// <summary>
/// 向写入流写入一行记录
/// </summary>
private bool AppentLine(FeatureOIDMap pFeatureOIDMap)
{
StringBuilder pline = new StringBuilder();
CoPointClass cpoint = null;
//常住内存索引
this.DwidList.Add(pFeatureOIDMap.ObjectID);
//
pline.Append(pFeatureOIDMap.ObjectID.ToString());
for (int i = 0; i < pFeatureOIDMap.PointArray.Count; i++)
{
cpoint=pFeatureOIDMap.PointArray[i] as CoPointClass;
pline.Append("," + cpoint.X.ToString() + "," + cpoint.Y.ToString());
}
return AppentLine(pline.ToString());
} //保存到txt文件中
public bool SaveToTxt()
{
bool rbc = false;
if (this.dt != null)
{
foreach(FeatureOIDMap featmap in this.dt.Values)
{
this.AppentLine(featmap);
}
rbc = true;
}
return rbc;
} /// <summary>
/// 关闭写入流
/// </summary>
public bool CloseTxt()
{
if (sw != null)
{
sw.Flush();
sw.Close();
sw.Dispose();
sw = null;
}
return true;
} //从txt中读取记录到m_dt表中 OK
public virtual bool ReadFromTxt()
{
this.Dispose();
int t_index = 0;
int bsm=0;
double x = 0;
double y = 0;
System.IO.StreamReader sr = new System.IO.StreamReader(this.RelationFileDir + "\\" + this.RelationFileName, Encoding.Default);
string line = sr.ReadLine();
while (line != null && line != "")
{
t_index += 1;
if (t_index % 100 == 0)
{
Application.DoEvents();
}
//向m_dt中加入一行记录
string[] lineArray = line.Split(new char[] { ',' });
bsm=int.Parse(lineArray[0]);
FeatureOIDMap feat_new = new FeatureOIDMap(bsm);
for (int i = 1; i < lineArray.Length; i+=2)
{
CoPointClass xpPoint = new CoPointClass();
x = 0;
y = 0;
double.TryParse(lineArray[i], out x);
double.TryParse(lineArray[i+1], out y);
xpPoint.X = x;
xpPoint.Y = y;
//
feat_new.PointArray.Add(xpPoint);
}
this.m_dt.Add(feat_new.ObjectID,feat_new);
//
line = sr.ReadLine();
}
sr.Close();
sr.Dispose();
sr = null;
return true;
} //从内存页面中选择记录集 OK
public FeatureOIDMap GetLine(int bsm)
{
FeatureOIDMap feat = null;
if (m_dt != null && m_dt.Count <= 0)
{
this.ReadFromTxt();
}
if (m_dt != null && m_dt.Count > 0)
{
feat = this.m_dt.GetIndexByOID(bsm);
}
return feat;
} #region IDisposable 成员 public void Dispose()
{
if (m_dt != null)
{
m_dt.Clear();
}
}
#endregion
}