/// <summary>
        /// 初始化新的DirectoryEntry
        /// </summary>
        /// <param name="parent">父节点</param>
        /// <param name="entryID">DirectoryEntryID</param>
        /// <param name="entryName">DirectoryEntry名称</param>
        /// <param name="entryType">DirectoryEntry类型</param>
        /// <param name="firstSectorID">第一个SectorID</param>
        /// <param name="length">内容大小</param>
        public DirectoryEntry(DirectoryEntry parent, UInt32 entryID, String entryName, DirectoryEntryType entryType, UInt32 firstSectorID, UInt32 length)
        {
            this._entryID = entryID;
            this._entryName = entryName;
            this._entryType = entryType;
            this._firstSectorID = firstSectorID;
            this._length = length;
            this._parent = parent;

            if (entryType == DirectoryEntryType.Root || entryType == DirectoryEntryType.Storage)
            {
                this._children = new List<DirectoryEntry>();
            }
        }
        private void ReadDirectoryEntry(DirectoryEntry rootEntry, UInt32 entryID)
        {
            UInt32 leftSiblingEntryID, rightSiblingEntryID, childEntryID;
            DirectoryEntry entry = GetDirectoryEntry(entryID, rootEntry, out leftSiblingEntryID, out rightSiblingEntryID, out childEntryID);

            if (entry == null || entry.EntryType == DirectoryEntryType.Invalid)
            {
                return;
            }

            rootEntry.AddChild(entry);

            if (leftSiblingEntryID < UInt32.MaxValue)//有左兄弟节点
            {
                this.ReadDirectoryEntry(rootEntry, leftSiblingEntryID);
            }

            if (rightSiblingEntryID < UInt32.MaxValue)//有右兄弟节点
            {
                this.ReadDirectoryEntry(rootEntry, rightSiblingEntryID);
            }

            if (childEntryID < UInt32.MaxValue)//有孩子节点
            {
                this.ReadDirectoryEntry(entry, childEntryID);
            }
        }
        private void ReadDirectory()
        {
            if (this._reader == null)
            {
                return;
            }

            this._dirSectors = new List<UInt32>();
            UInt32 sectorID = this._dirStartSectorID;

            while (true)
            {
                this._dirSectors.Add(sectorID);
                sectorID = this.GetNextSectorID(sectorID);

                if (sectorID == CompoundBinaryFile.EndOfChain)
                {
                    break;
                }
            }

            UInt32 leftSiblingEntryID, rightSiblingEntryID, childEntryID;
            this._dirRootEntry = GetDirectoryEntry(0, null, out leftSiblingEntryID, out rightSiblingEntryID, out childEntryID);
            this.ReadDirectoryEntry(this._dirRootEntry, childEntryID);
        }
        private DirectoryEntry GetDirectoryEntry(UInt32 entryID, DirectoryEntry parentEntry, out UInt32 leftSiblingEntryID, out UInt32 rightSiblingEntryID, out UInt32 childEntryID)
        {
            leftSiblingEntryID = UInt16.MaxValue;
            rightSiblingEntryID = UInt16.MaxValue;
            childEntryID = UInt16.MaxValue;

            this._stream.Seek(GetDirectoryEntryOffset(entryID), SeekOrigin.Begin);

            if (this._stream.Position >= this._length)
            {
                return null;
            }

            StringBuilder temp = new StringBuilder();
            for (Int32 i = 0; i < 32; i++)
            {
                temp.Append((Char)this._reader.ReadUInt16());
            }

            UInt16 nameLen = this._reader.ReadUInt16();
            String name = (temp.ToString(0, (temp.Length < (nameLen / 2 - 1) ? temp.Length : nameLen / 2 - 1)));
            Byte type = this._reader.ReadByte();

            if (type > 5)
            {
                return null;
            }

            this._stream.Seek(1, SeekOrigin.Current);
            leftSiblingEntryID = this._reader.ReadUInt32();
            rightSiblingEntryID = this._reader.ReadUInt32();
            childEntryID = this._reader.ReadUInt32();

            this._stream.Seek(36, SeekOrigin.Current);
            UInt32 sectorID = this._reader.ReadUInt32();
            UInt32 length = this._reader.ReadUInt32();

            return new DirectoryEntry(parentEntry, entryID, name, (DirectoryEntryType)type, sectorID, length);
        }
 protected Int64 GetEntryOffset(DirectoryEntry entry)
 {
     if (entry.Length >= this._miniCutoffSize)
     {
         return GetSectorOffset(entry.SectorID);
     }
     else
     {
         return GetMiniSectorOffset(entry.SectorID);
     }
 }
        public void AddChild(DirectoryEntry entry)
        {
            if (this._children == null)
            {
                this._children = new List<DirectoryEntry>();
            }

            this._children.Add(entry);
        }
        private void ReadEntryOrder(DirectoryEntry entry)
        {
            List<UInt32> sectorIDs = new List<UInt32>();
            UInt32 sectorID = entry.FirstSectorID;

            while (true)
            {
                if (sectorID == CompoundBinaryFile.EndOfChain || sectorID == CompoundBinaryFile.FreeSector)
                {
                    break;
                }

                sectorIDs.Add(sectorID);
                sectorID = this.GetNextSectorID(sectorID, (entry.Length >= this._miniCutoffSize));
            }

            this._entrySectorIDs[entry.EntryID] = sectorIDs;
        }
        private void CopyEntryData(DirectoryEntry entry)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                List<UInt32> sectorIDs = this._entrySectorIDs[entry.EntryID];

                for (Int32 i = 0; i < sectorIDs.Count; i++)
                {
                    Int64 offset = GetSectorOffset(sectorIDs[i], (entry.Length >= this._miniCutoffSize));
                    UInt32 count = (entry.Length >= this._miniCutoffSize) ? this._sectorSize : this._miniSectorSize;

                    Byte[] buff = new Byte[count];
                    this._stream.Seek(offset, SeekOrigin.Begin);
                    this._stream.Read(buff, 0, (Int32)count);

                    stream.Write(buff, 0, (Int32)count);
                }

                this._entryData[entry.EntryID] = stream.ToArray();
            }
        }
        protected void LoadEntry(DirectoryEntry entry, Action<Stream, BinaryReader> action)
        {
            if (this._entryData == null)
            {
                return;
            }

            using (MemoryStream stream = new MemoryStream(this._entryData[entry.EntryID]))
            {
                BinaryReader reader = new BinaryReader(stream);

                action(stream, reader);

                reader.Close();
                reader.Dispose();
            }
        }