/// <summary> /// 初始化文件系统的新实例。 /// </summary> /// <param name="fullPath">文件系统完整路径。</param> /// <param name="access">文件系统访问方式。</param> /// <param name="stream">文件系统流。</param> private FileSystem(string fullPath, FileSystemAccess access, FileSystemStream stream) { if (string.IsNullOrEmpty(fullPath)) { throw new GameFrameworkException("Full path is invalid."); } if (access == FileSystemAccess.Unspecified) { throw new GameFrameworkException("Access is invalid."); } if (stream == null) { throw new GameFrameworkException("Stream is invalid."); } m_FullPath = fullPath; m_Access = access; m_Stream = stream; m_FileDatas = new Dictionary <string, int>(StringComparer.Ordinal); m_BlockDatas = new List <BlockData>(); m_FreeBlockIndexes = new GameFrameworkMultiDictionary <int, int>(); m_StringDatas = new SortedDictionary <int, StringData>(); m_FreeStringDatas = new Queue <KeyValuePair <int, StringData> >(); m_HeaderData = default(HeaderData); m_BlockDataOffset = 0; m_StringDataOffset = 0; m_FileDataOffset = 0; Utility.Marshal.EnsureCachedHGlobalSize(CachedBytesLength); }
/// <summary> /// 创建文件系统。 /// </summary> /// <param name="fullPath">要创建的文件系统的完整路径。</param> /// <param name="access">要创建的文件系统的访问方式。</param> /// <param name="stream">要创建的文件系统的文件系统流。</param> /// <param name="maxFileCount">要创建的文件系统的最大文件数量。</param> /// <param name="maxBlockCount">要创建的文件系统的最大块数据数量。</param> /// <returns>创建的文件系统。</returns> public static FileSystem Create(string fullPath, FileSystemAccess access, FileSystemStream stream, int maxFileCount, int maxBlockCount) { if (maxFileCount <= 0) { throw new GameFrameworkException("Max file count is invalid."); } if (maxBlockCount <= 0) { throw new GameFrameworkException("Max block count is invalid."); } if (maxFileCount > maxBlockCount) { throw new GameFrameworkException("Max file count can not larger than max block count."); } FileSystem fileSystem = new FileSystem(fullPath, access, stream); fileSystem.m_HeaderData = new HeaderData(maxFileCount, maxBlockCount); CalcOffsets(fileSystem); Utility.Marshal.StructureToBytes(fileSystem.m_HeaderData, HeaderDataSize, s_CachedBytes); try { stream.Write(s_CachedBytes, 0, HeaderDataSize); stream.SetLength(fileSystem.m_FileDataOffset); return(fileSystem); } catch { fileSystem.Shutdown(); return(null); } }
/// <summary> /// 加载文件系统。 /// </summary> /// <param name="fullPath">要加载的文件系统的完整路径。</param> /// <param name="access">要加载的文件系统的访问方式。</param> /// <param name="stream">要加载的文件系统的文件系统流。</param> /// <returns>加载的文件系统。</returns> public static FileSystem Load(string fullPath, FileSystemAccess access, FileSystemStream stream) { FileSystem fileSystem = new FileSystem(fullPath, access, stream); stream.Read(s_CachedBytes, 0, HeaderDataSize); fileSystem.m_HeaderData = Utility.Marshal.BytesToStructure <HeaderData>(HeaderDataSize, s_CachedBytes); CalcOffsets(fileSystem); fileSystem.m_BlockDatas.Capacity = fileSystem.m_HeaderData.BlockCount; for (int i = 0; i < fileSystem.m_HeaderData.BlockCount; i++) { stream.Read(s_CachedBytes, 0, BlockDataSize); BlockData blockData = Utility.Marshal.BytesToStructure <BlockData>(BlockDataSize, s_CachedBytes); fileSystem.m_BlockDatas.Add(blockData); } for (int i = 0; i < fileSystem.m_BlockDatas.Count; i++) { BlockData blockData = fileSystem.m_BlockDatas[i]; if (blockData.Using) { StringData stringData = fileSystem.ReadStringData(blockData.StringIndex); fileSystem.m_StringDatas.Add(blockData.StringIndex, stringData); fileSystem.m_FileDatas.Add(stringData.GetString(fileSystem.m_HeaderData.GetEncryptBytes()), i); } else { fileSystem.m_FreeBlockIndexes.Add(blockData.Length, i); } } return(fileSystem); }
/// <summary> /// 加载文件系统。 /// </summary> /// <param name="fullPath">要加载的文件系统的完整路径。</param> /// <param name="access">要加载的文件系统的访问方式。</param> /// <param name="stream">要加载的文件系统的文件系统流。</param> /// <returns>加载的文件系统。</returns> public static FileSystem Load(string fullPath, FileSystemAccess access, FileSystemStream stream) { FileSystem fileSystem = new FileSystem(fullPath, access, stream); stream.Read(s_CachedBytes, 0, HeaderDataSize); fileSystem.m_HeaderData = Utility.Marshal.BytesToStructure <HeaderData>(HeaderDataSize, s_CachedBytes); if (!fileSystem.m_HeaderData.IsValid) { return(null); } CalcOffsets(fileSystem); if (fileSystem.m_BlockDatas.Capacity < fileSystem.m_HeaderData.BlockCount) { fileSystem.m_BlockDatas.Capacity = fileSystem.m_HeaderData.BlockCount; } for (int i = 0; i < fileSystem.m_HeaderData.BlockCount; i++) { stream.Read(s_CachedBytes, 0, BlockDataSize); BlockData blockData = Utility.Marshal.BytesToStructure <BlockData>(BlockDataSize, s_CachedBytes); fileSystem.m_BlockDatas.Add(blockData); } for (int i = 0; i < fileSystem.m_BlockDatas.Count; i++) { BlockData blockData = fileSystem.m_BlockDatas[i]; if (blockData.Using) { StringData stringData = fileSystem.ReadStringData(blockData.StringIndex); fileSystem.m_StringDatas.Add(blockData.StringIndex, stringData); fileSystem.m_FileDatas.Add(stringData.GetString(fileSystem.m_HeaderData.GetEncryptBytes()), i); } else { fileSystem.m_FreeBlockIndexes.Add(blockData.Length, i); } } int index = 0; foreach (KeyValuePair <int, StringData> i in fileSystem.m_StringDatas) { while (index < i.Key) { fileSystem.m_FreeStringIndexes.Enqueue(index++); } index++; } return(fileSystem); }
/// <summary> /// 创建文件系统。 /// </summary> /// <param name="fullPath">要创建的文件系统的完整路径。</param> /// <param name="access">要创建的文件系统的访问方式。</param> /// <param name="maxFileCount">要创建的文件系统的最大文件数量。</param> /// <param name="maxBlockCount">要创建的文件系统的最大块数据数量。</param> /// <returns>创建的文件系统。</returns> public IFileSystem CreateFileSystem(string fullPath, FileSystemAccess access, int maxFileCount, int maxBlockCount) { if (m_FileSystemHelper == null) { throw new GameFrameworkException("File system helper is invalid."); } if (string.IsNullOrEmpty(fullPath)) { throw new GameFrameworkException("Full path is invalid."); } if (access == FileSystemAccess.Unspecified) { throw new GameFrameworkException("Access is invalid."); } if (access == FileSystemAccess.Read) { throw new GameFrameworkException("Access read is invalid."); } fullPath = Utility.Path.GetRegularPath(fullPath); if (m_FileSystems.ContainsKey(fullPath)) { throw new GameFrameworkException(Utility.Text.Format("File system '{0}' is already exist.", fullPath)); } FileSystemStream fileSystemStream = m_FileSystemHelper.CreateFileSystemStream(fullPath, access, true); if (fileSystemStream == null) { throw new GameFrameworkException(Utility.Text.Format("Create file system stream for '{0}' failure.", fullPath)); } FileSystem fileSystem = FileSystem.Create(fullPath, access, fileSystemStream, maxFileCount, maxBlockCount); if (fileSystem == null) { throw new GameFrameworkException(Utility.Text.Format("Create file system '{0}' failure.", fullPath)); } m_FileSystems.Add(fullPath, fileSystem); return(fileSystem); }
/// <summary> /// 加载文件系统。 /// </summary> /// <param name="fullPath">要加载的文件系统的完整路径。</param> /// <param name="access">要加载的文件系统的访问方式。</param> /// <param name="stream">要加载的文件系统的文件系统流。</param> /// <returns>加载的文件系统。</returns> public static FileSystem Load(string fullPath, FileSystemAccess access, FileSystemStream stream) { FileSystem fileSystem = new FileSystem(fullPath, access, stream); stream.Read(s_CachedBytes, 0, HeaderDataSize); fileSystem.m_HeaderData = Utility.Marshal.BytesToStructure <HeaderData>(HeaderDataSize, s_CachedBytes); if (!fileSystem.m_HeaderData.IsValid) { throw new GameFrameworkException(Utility.Text.Format("File system '{0}' is invalid.", fullPath)); } CalcOffsets(fileSystem); if (fileSystem.m_BlockDatas.Capacity < fileSystem.m_HeaderData.BlockCount) { fileSystem.m_BlockDatas.Capacity = fileSystem.m_HeaderData.BlockCount; } for (int i = 0; i < fileSystem.m_HeaderData.BlockCount; i++) { stream.Read(s_CachedBytes, 0, BlockDataSize); BlockData blockData = Utility.Marshal.BytesToStructure <BlockData>(BlockDataSize, s_CachedBytes); fileSystem.m_BlockDatas.Add(blockData); } for (int i = 0; i < fileSystem.m_BlockDatas.Count; i++) { BlockData blockData = fileSystem.m_BlockDatas[i]; if (blockData.Using) { StringData stringData = fileSystem.ReadStringData(blockData.StringIndex); fileSystem.m_StringDatas.Add(blockData.StringIndex, stringData); fileSystem.m_FileDatas.Add(stringData.GetString(fileSystem.m_HeaderData.GetEncryptBytes()), i); } else { fileSystem.m_FreeBlockIndexes.Add(blockData.Length, i); } } return(fileSystem); }