/// <summary> /// 保存包至 /// </summary> /// <param name="Path">文件路径</param> public void Save(string FilePath) { string tOrgFile = null; if (FilePath == m_FilePath) { tOrgFile = FilePath; FilePath += ".temp"; } FileStream tNewStream = null; // 最高权限打开流 try { tNewStream = new FileStream(FilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); } catch (IOException e) { throw new FCYExcpSaveErr(e.Message); } m_FilePath = FilePath; // 写出头 writeDataHeader(tNewStream); // 创建Xml数据 XmlDocument tXmlDoc = new XmlDocument(); XmlElement tRootElement = tXmlDoc.CreateElement("Res"); // 收集所有数据 RootNode.Sort(); for (int i = 0; i < RootNode.NodeList.Count; i++) { RootNode.NodeList[i].WriteToStream(tNewStream, tRootElement); } // 写入Xml tXmlDoc.AppendChild(tRootElement); // 写入内存流 MemoryStream tXmlMemStream = new MemoryStream(); XmlWriterSettings tXmlSetting = new XmlWriterSettings(); tXmlSetting.Encoding = Encoding.Unicode; // 设置格式 tXmlSetting.OmitXmlDeclaration = true; // 关闭声明头 XmlWriter tXmlWriter = XmlWriter.Create(tXmlMemStream, tXmlSetting); tXmlDoc.Save(tXmlWriter); // 记录当前位置 m_IndexOffset = (uint)tNewStream.Position; // 写出Xml原始长度 BinaryWriter tWriter = new BinaryWriter(tNewStream); tWriter.Write((uint)tXmlMemStream.Length); // 压缩数据并保存到流 tXmlMemStream.Seek(0, SeekOrigin.Begin); FCYResPackageHelper.DeflateEncodeTo(tXmlMemStream, tNewStream, (int)tXmlMemStream.Length); // 重写文件头 writeDataHeader(tNewStream); // 关闭Xml内存 tXmlWriter.Close(); // 关闭原始流 if (BaseStream != null) { BaseStream.Close(); } if (m_BaseStream != null) { m_BaseStream.Close(); m_BaseStream = null; } m_BaseStream = tNewStream; GC.Collect(); if (tOrgFile != null) { File.Delete(tOrgFile); Save(tOrgFile); File.Delete(FilePath); } }
internal override void WriteToStream(Stream pOut, XmlElement ParentXml) { // 记下当前位置 long tPos = pOut.Position; // 是否是外部流 if (m_Stream == null) { // 外部流 Stream tBaseStream = m_Package.BaseStream; // 寻址 tBaseStream.Seek(FCYResPackage.HeaderSize + m_MainDataOffset, SeekOrigin.Begin); // 直接复制 FCYResPackageHelper.FillStream(tBaseStream, pOut, (int)(IsCompressed ? DataCompressedSize : DataRealSize)); } else { // 内部流 if (IsCompressed) { long tPosStart = pOut.Position; // 压缩流 m_Stream.Seek(0, SeekOrigin.Begin); FCYResPackageHelper.DeflateEncodeTo(m_Stream, pOut, (int)DataRealSize); long tPosEnd = pOut.Position; // 关闭内部流 m_Stream.Close(); m_Stream = null; // 更新数据 m_DataCompressedSize = (uint)(tPosEnd - tPosStart); } else { // 直接复制 m_Stream.Seek(0, SeekOrigin.Begin); FCYResPackageHelper.FillStream(m_Stream, pOut, (int)DataRealSize); } } // 更新位置 m_MainDataOffset = (uint)tPos - FCYResPackage.HeaderSize; // 准备Xml数据 XmlElement tElement = ParentXml.OwnerDocument.CreateElement("Node"); tElement.SetAttribute("Name", Name); tElement.SetAttribute("OrgSize", DataRealSize.ToString()); tElement.SetAttribute("IsCompressed", IsCompressed ? "yes" : "no"); tElement.SetAttribute("CompressedSize", DataCompressedSize.ToString()); tElement.SetAttribute("Offset", DataOffset.ToString()); tElement.InnerText = AdditionData; // 写出Xml数据 ParentXml.AppendChild(tElement); }