Beispiel #1
0
        public void Init()
        {
            FileInfo fi = new FileInfo(_filename);

            if (!fi.Directory.Exists)
            {
                fi.Directory.Create();
            }
            _fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite);
            if (_fs.Length < SectorToByte(2))
            {
                byte[] headByte = Enumerable.Repeat((byte)0x00, (int)SectorToByte(2)).ToArray();
                _fs.Position = 0;
                _fs.Write(headByte, 0, headByte.Length);
            }
            _headData     = new ChunkHeadData[REGION_WIDTH, REGION_DEPTH];
            _useSector    = new ArrayList(new bool[ByteToSector(_fs.Length)]);
            _useSector[0] = true;
            _useSector[1] = true;
            for (int x = 0; x < REGION_WIDTH; x++)
            {
                for (int z = 0; z < REGION_DEPTH; z++)
                {
                    _headData[x, z] = new ChunkHeadData(x, z);
                    ReadHeadData(x, z);
                }
            }
            _cs = new ChunkStream();
        }
Beispiel #2
0
        //获取到的块数据
        public bool GetChunkData(int x, int z, Chunk chunk)
        {
            if (_headData[x, z].status == ChunkDataStatus.Not_Create)
            {
                return(false);
            }
            _fs.Position = SectorToByte(_headData[x, z].BlockOffset) + 5;
            _cs.SetLength(0);
            _cs.Write(_fs, _headData[x, z].Length);
            _cs.Position = 0;
            IMTBCompress compress = MTBCompressFactory.GetCompress(_headData[x, z].CompressionType);

            _cs          = (ChunkStream)compress.Decompress(_cs);
            _cs.Position = 0;
            chunk.Deserialize(_cs);
            return(true);
        }
Beispiel #3
0
        //保存块的字节数据
        public void SaveChunkData(int x, int z, Chunk chunk)
        {
            _cs.SetLength(0);
            chunk.Serialize(_cs);
            _cs.Position = 0;
            IMTBCompress compress = MTBCompressFactory.GetCompress(_compressType);

            _cs = (ChunkStream)compress.Encompress(_cs);
            byte[] chunkSize = new byte[4];

            Serialization.WriteIntToByteArr(chunkSize, (int)_cs.Length);
            int singleChunkLength = (int)_cs.Length + 5;

            int blockLength = ByteToSector(singleChunkLength);

            ClearChunkData(x, z);
            int  blockOffset = GetChunkCanSavedSector(blockLength);
            long blockOffsetStartByteIndex = SectorToByte(blockOffset);

            _fs.Position = blockOffsetStartByteIndex;
            //写入区块长度
            _fs.Write(chunkSize, 0, chunkSize.Length);
            //写入压缩格式
            _fs.WriteByte((byte)compress.CompressType);
            //写入区块压缩数据
            _cs.Position = 0;
            _cs.Read(_fs, (int)_cs.Length);
            int startPosition = (x * REGION_DEPTH + z) * 4;

            _fs.Position = startPosition;
            byte[] blockOffsetByte = new byte[4];
            Serialization.WriteIntToByteArr(blockOffsetByte, blockOffset);
            _fs.Write(blockOffsetByte, 0, 3);
            _fs.WriteByte((byte)blockLength);

            //更新可存储标志,并将块后面不足一个扇区的部分写0x00
            for (int i = blockOffset; i < blockOffset + blockLength; i++)
            {
                _useSector[i] = true;
            }
            long chunkEnd  = blockOffsetStartByteIndex + singleChunkLength;
            long sectorEnd = blockOffsetStartByteIndex + SectorToByte(blockLength);

            if (chunkEnd < sectorEnd)
            {
                _fs.Position = chunkEnd;
                byte[] extendByte = Enumerable.Repeat((byte)0x00, (int)(sectorEnd - chunkEnd)).ToArray();
                _fs.Write(extendByte, 0, extendByte.Length);
            }
            //截取文件最后没有使用的扇区
            int lastUseSectorIndex = GetLastUseSectorIndex();

            if (lastUseSectorIndex != -1 && lastUseSectorIndex != _useSector.Count - 1)
            {
                int truncatedIndex = lastUseSectorIndex + 1;
                _useSector.RemoveRange(truncatedIndex, _useSector.Count - truncatedIndex);
                _fs.SetLength(SectorToByte(truncatedIndex));
            }
            //更新headData数据
            _headData[x, z].BlockOffset     = blockOffset;
            _headData[x, z].BlockLength     = (byte)blockLength;
            _headData[x, z].Length          = (int)_cs.Length;
            _headData[x, z].status          = ChunkDataStatus.OK;
            _headData[x, z].CompressionType = compress.CompressType;
        }