我可以使用GlobalAddAtom
創建一個全局原子,如果我已經知道與原子關聯的字符串,我可以再次使用GlobalFindAtom
找到該原子。但有沒有辦法找到所有相關字符串匹配給定部分字符串的原子?從部分字符串中查找全局原子
例如,假設我有一個字符串爲「Hello,World!」的原子。我怎樣才能通過搜索「Hello」來找到原子?
我可以使用GlobalAddAtom
創建一個全局原子,如果我已經知道與原子關聯的字符串,我可以再次使用GlobalFindAtom
找到該原子。但有沒有辦法找到所有相關字符串匹配給定部分字符串的原子?從部分字符串中查找全局原子
例如,假設我有一個字符串爲「Hello,World!」的原子。我怎樣才能通過搜索「Hello」來找到原子?
不幸的是,您所描述的行爲不適用於Atom表。這是因爲Windows中的Atom表基本上是哈希表,而映射進程處理整個字符串而不是部分。
當然,它幾乎聽起來像這將是可能的,因爲從MSDN documentation報價:
應用程序也可以使用本地原子表,以節省時間,特定的搜索字符串時。要執行搜索,應用程序只需將搜索字符串放在原子表中,並將結果原子與相關結構中的原子進行比較。比較原子通常比比較字符串更快。
但是,它們指的是完全匹配。與軟件當前可用資源的可能性相比,這種限制似乎有點過時了。然而,早在Win16版本中就可以使用原子,在那個時候,這個工具允許應用程序在最小的內存中有效地管理字符串數據。現在仍然使用原子來管理窗口類名稱,並且仍然在減少多個存儲的字符串副本的佔用空間方面提供可觀的好處。
如果您需要高效地存儲字符串數據並能夠通過部分匹配來掃描,Suffix Tree可能會滿足或超出您的需求。
它實際上可以完成,但只能通過掃描它們。在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);
啊,我明白了。當你建議MSDN文檔使我認爲可以搜索部分匹配的原子時,你是對的。是否可以創建後綴樹作爲全局可訪問的資源(如在兩個或更多進程中運行的不同權限級別和/或帳戶可以從中讀取)? – 2011-04-21 22:33:10
在您描述的場景中,您可能會更好地服務於尋找第三方組件來滿足您的需求。如果你可以使用.NET 2.0,Lucene.Net非常適合索引文本數據;你也可以在會話之間獲得持久性。如果您只需要一個具有短期生命週期的存儲庫(僅適用於內存),則可以考慮使COM服務器或Windows服務集中存儲後綴樹,然後從其他應用程序進程調解訪問它。 – meklarian 2011-04-21 22:53:06