Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }