private void ReadAllKeyItems()
            {
                List <ItemData> itemDatas = null;

                for (int i = 0, imax = mActiveKeyReaders.Count; i < imax; i++)
                {
                    XmlIdReader r = mActiveKeyReaders[i];
                    while (r.MoveNext())
                    {
                        string   itemKey = r.CurrentKeyItem.Key;
                        ItemData itemData;
                        itemData.obj  = r.CurrentKeyItem.Value;
                        itemData.type = r.type;
                        if (mKeyDatas.TryGetValue(itemKey, out itemDatas))
                        {
                            itemDatas.Add(itemData);
                        }
                        else
                        {
                            itemDatas = new List <ItemData>();
                            itemDatas.Add(itemData);
                            mKeyDatas.Add(itemKey, itemDatas);
                        }
                    }
                }
                mActiveKeyReaders.Clear();
            }
 public SheetDatas(List <string> files, List <Type> itemTypes)
 {
     for (int i = 0, imax = files.Count; i < imax; i++)
     {
         try
         {
             string      path = string.Format("{0}/../{1}", Application.dataPath, files[i]);
             XmlIdReader r    = new XmlIdReader(path, itemTypes[i]);
             if (i == 0)
             {
                 mStrKey = r.isStrKey;
             }
             else if (r.isStrKey != mStrKey)
             {
                 throw new Exception("Multi key types in one sheet !\n" + string.Join("\n", files.ToArray()));
             }
             if (mStrKey)
             {
                 mActiveKeyReaders.Add(r);
             }
             else
             {
                 mActiveIdReaders.Add(r);
             }
         }
         catch (System.Exception ex)
         {
             Debug.LogError(ex.ToString());
         }
     }
 }
            public T GetItem <T>(string key)
            {
                if (!mStrKey)
                {
                    return(default(T));
                }
                ReadAllKeyItems();
                List <ItemData> itemDatas = null;

                if (mKeyDatas.TryGetValue(key, out itemDatas) && itemDatas.Count > 0)
                {
                    for (int i = 0, imax = itemDatas.Count; i < imax; i++)
                    {
                        if (itemDatas[i].obj is T)
                        {
                            return((T)itemDatas[i].obj);
                        }
                    }
                }
                object obj = null;

                while (obj == null && mActiveKeyReaders.Count > 0)
                {
                    for (int i = 0, imax = mActiveKeyReaders.Count; i < imax; i++)
                    {
                        XmlIdReader r       = mActiveKeyReaders[i];
                        bool        canRead = false;
                        while (canRead = r.MoveNext())
                        {
                            string   itemKey = r.CurrentKeyItem.Key;
                            ItemData itemData;
                            itemData.obj  = r.CurrentKeyItem.Value;
                            itemData.type = r.type;
                            if (mKeyDatas.TryGetValue(itemKey, out itemDatas))
                            {
                                itemDatas.Add(itemData);
                            }
                            else
                            {
                                itemDatas = new List <ItemData>();
                                itemDatas.Add(itemData);
                                mKeyDatas.Add(itemKey, itemDatas);
                            }
                            if (itemKey == key && (itemData.obj is T))
                            {
                                obj = itemData.obj;
                                break;
                            }
                            if (string.Compare(itemKey, key) > 0)
                            {
                                break;
                            }
                        }
                        if (!canRead)
                        {
                            mCachedInts.Add(i);
                        }
                        if (obj != null)
                        {
                            break;
                        }
                    }
                    for (int i = mCachedInts.Count - 1; i >= 0; i--)
                    {
                        mActiveKeyReaders.RemoveAt(mCachedInts[i]);
                    }
                    mCachedInts.Clear();
                }
                if (obj != null && (obj is T))
                {
                    return((T)obj);
                }
                return(default(T));
            }
            // 根据string型id直接返回数据流,Lua层使用;
            public byte[] GetItemBytes(string key, out string sheetType)
            {
                sheetType = "";
                if (!mStrKey)
                {
                    return(null);
                }

                object          obj       = null;
                Type            type      = null;
                List <ItemData> itemDatas = null;

                if (mKeyDatas.TryGetValue(key, out itemDatas))
                {
                    for (int i = 0, imax = itemDatas.Count; i < imax; i++)
                    {
                        obj = itemDatas[i].obj;
                        if (obj != null)
                        {
                            type = itemDatas[i].type;
                            break;
                        }
                    }
                }

                while (obj == null && mActiveKeyReaders.Count > 0)
                {
                    for (int i = 0, imax = mActiveKeyReaders.Count; i < imax; i++)
                    {
                        XmlIdReader r       = mActiveKeyReaders[i];
                        bool        canRead = false;
                        while (canRead = r.MoveNext())
                        {
                            string   itemKey = r.CurrentKeyItem.Key;
                            ItemData itemData;
                            itemData.obj  = r.CurrentKeyItem.Value;
                            itemData.type = r.type;
                            if (mKeyDatas.TryGetValue(itemKey, out itemDatas))
                            {
                                itemDatas.Add(itemData);
                            }
                            else
                            {
                                itemDatas = new List <ItemData>();
                                itemDatas.Add(itemData);
                                mKeyDatas.Add(itemKey, itemDatas);
                            }
                            if (itemKey == key)
                            {
                                obj  = itemData.obj;
                                type = itemData.type;
                                break;
                            }
                            if (string.Compare(itemKey, key) > 0)
                            {
                                break;
                            }
                        }
                        if (!canRead)
                        {
                            mCachedInts.Add(i);
                        }
                        if (obj != null)
                        {
                            break;
                        }
                    }
                    for (int i = mCachedInts.Count - 1; i >= 0; i--)
                    {
                        mActiveKeyReaders.RemoveAt(mCachedInts[i]);
                    }
                    mCachedInts.Clear();
                }
                if (obj != null && type != null)
                {
                    sheetType = type.ToString();
                    MemoryStream dataStream = new MemoryStream();
                    RuntimeTypeModel.Default.SerializeWithLengthPrefix(dataStream, obj, type, ProtoBuf.PrefixStyle.Fixed32, 0);

                    dataStream.Position = 0;
                    int    length = DatabaseStreamReader.ReadInt(dataStream);
                    byte[] bytes  = new byte[length];
                    dataStream.Read(bytes, 0, length);
                    dataStream.Close();
                    return(bytes);
                }
                return(null);
            }