2011-04-21 21 views
3

我可以使用GlobalAddAtom创建一个全局原子,如果我已经知道与原子关联的字符串,我可以再次使用GlobalFindAtom找到该原子。但有没有办法找到所有相关字符串匹配给定部分字符串的原子?从部分字符串中查找全局原子

例如,假设我有一个字符串为“Hello,World!”的原子。我怎样才能通过搜索“Hello”来找到原子?

回答

4

不幸的是,您所描述的行为不适用于Atom表。这是因为Windows中的Atom表基本上是哈希表,而映射进程处理整个字符串而不是部分。

当然,它几乎听起来像这将是可能的,因为从MSDN documentation报价:

应用程序也可以使用本地原子表,以节省时间,特定的搜索字符串时。要执行搜索,应用程序只需将搜索字符串放在原子表中,并将结果原子与相关结构中的原子进行比较。比较原子通常比比较字符串更快。

但是,它们指的是完全匹配。与软件当前可用资源的可能性相比,这种限制似乎有点过时了。然而,早在Win16版本中就可以使用原子,在那个时候,这个工具允许应用程序在最小的内存中有效地管理字符串数据。现在仍然使用原子来管理窗口类名称,并且仍然在减少多个存储的字符串副本的占用空间方面提供可观的好处。

如果您需要高效地存储字符串数据并能够通过部分匹配来扫描,Suffix Tree可能会满足或超出您的需求。

+0

啊,我明白了。当你建议MSDN文档使我认为可以搜索部分匹配的原子时,你是对的。是否可以创建后缀树作为全局可访问的资源(如在两个或更多进程中运行的不同权限级别和/或帐户可以从中读取)? – 2011-04-21 22:33:10

+0

在您描述的场景中,您可能会更好地服务于寻找第三方组件来满足您的需求。如果你可以使用.NET 2.0,Lucene.Net非常适合索引文本数据;你也可以在会话之间获得持久性。如果您只需要一个具有短期生命周期的存储库(仅适用于内存),则可以考虑使COM服务器或Windows服务集中存储后缀树,然后从其他应用程序进程调解访问它。 – meklarian 2011-04-21 22:53:06

2

它实际上可以完成,但只能通过扫描它们。在LINQPad 5中,我的机器可以在0.025秒内完成,所以速度非常快。这里是一个示例实现:

void Main() 
{ 
    const string atomPrefix = "Hello"; 
    const int bufferSize = 1024; 
    ushort smallestAtomIndex = 0XC000; 
    var buffer = new StringBuilder(bufferSize); 
    var results = new List<string>(); 
    for (ushort atomIndex = smallestAtomIndex; atomIndex < ushort.MaxValue; atomIndex++) 
    { 
    var resultLength = GlobalGetAtomName(atomIndex, buffer, bufferSize); 
    if (buffer.ToString().StartsWith(atomPrefix)) 
    { 
     results.Add($"{buffer} - {atomIndex}"); 
    } 
    buffer.Clear(); 
    } 

    results.Dump(); 
} 

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern uint GlobalGetAtomName(ushort atom, StringBuilder buffer, int size); 
相关问题