private void InitCompleted() { var fileInfo = new FileInfo(_filename); if (!fileInfo.Exists) { throw new ChunkFileNotExistException(_filename); } _isCompleted = true; using (var fileStream = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, _chunkConfig.ChunkReadBuffer, FileOptions.None)) { using (var reader = new BinaryReader(fileStream)) { _chunkHeader = ReadHeader(fileStream, reader); _chunkFooter = ReadFooter(fileStream, reader); CheckCompletedFileChunk(); } } _dataPosition = _chunkFooter.ChunkDataTotalSize; _flushedDataPosition = _chunkFooter.ChunkDataTotalSize; if (_isMemoryChunk) { LoadFileChunkToMemory(); } else { SetFileAttributes(); } InitializeReaderWorkItems(); _lastActiveTime = DateTime.Now; }
private void InitNew(int chunkNumber) { var chunkDataSize = 0; if (_chunkConfig.ChunkDataSize > 0) { chunkDataSize = _chunkConfig.ChunkDataSize; } else { chunkDataSize = _chunkConfig.ChunkDataUnitSize * _chunkConfig.ChunkDataCount; } _chunkHeader = new ChunkHeader(chunkNumber, chunkDataSize); _isCompleted = false; var fileSize = ChunkHeader.Size + _chunkHeader.ChunkDataTotalSize + ChunkFooter.Size; var writeStream = default(Stream); var tempFilename = string.Format("{0}.{1}.tmp", _filename, Guid.NewGuid()); var tempFileStream = default(FileStream); try { if (_isMemoryChunk) { _cachedLength = fileSize; _cachedData = Marshal.AllocHGlobal(_cachedLength); writeStream = new UnmanagedMemoryStream((byte *)_cachedData, _cachedLength, _cachedLength, FileAccess.ReadWrite); writeStream.Write(_chunkHeader.AsByteArray(), 0, ChunkHeader.Size); } else { var fileInfo = new FileInfo(_filename); if (fileInfo.Exists) { File.SetAttributes(_filename, FileAttributes.Normal); File.Delete(_filename); } tempFileStream = new FileStream(tempFilename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read, _chunkConfig.ChunkWriteBuffer, FileOptions.None); tempFileStream.SetLength(fileSize); tempFileStream.Write(_chunkHeader.AsByteArray(), 0, ChunkHeader.Size); tempFileStream.Flush(true); tempFileStream.Close(); File.Move(tempFilename, _filename); writeStream = new FileStream(_filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, _chunkConfig.ChunkWriteBuffer, FileOptions.SequentialScan); SetFileAttributes(); } writeStream.Position = ChunkHeader.Size; _dataPosition = 0; _flushedDataPosition = 0; _writerWorkItem = new WriterWorkItem(new ChunkFileStream(writeStream, _chunkConfig.FlushOption)); InitializeReaderWorkItems(); if (!_isMemoryChunk) { if (_chunkConfig.EnableCache) { var chunkSize = (ulong)GetChunkSize(_chunkHeader); if (ChunkUtil.IsMemoryEnoughToCacheChunk(chunkSize, (uint)_chunkConfig.ChunkCacheMaxPercent)) { try { _memoryChunk = CreateNew(_filename, chunkNumber, _chunkManager, _chunkConfig, true); } catch (OutOfMemoryException) { _cacheItems = new CacheItem[_chunkConfig.ChunkLocalCacheSize]; } catch (Exception ex) { _logger.Error(string.Format("Failed to cache new chunk {0}", this), ex); _cacheItems = new CacheItem[_chunkConfig.ChunkLocalCacheSize]; } } else { _cacheItems = new CacheItem[_chunkConfig.ChunkLocalCacheSize]; } } else { _cacheItems = new CacheItem[_chunkConfig.ChunkLocalCacheSize]; } } } catch { if (!_isMemoryChunk) { if (tempFileStream != null) { Helper.EatException(() => tempFileStream.Close()); } if (File.Exists(tempFilename)) { Helper.EatException(() => { File.SetAttributes(tempFilename, FileAttributes.Normal); File.Delete(tempFilename); }); } } throw; } _lastActiveTime = DateTime.Now; }
private int GetChunkSize(ChunkHeader chunkHeader) { return(ChunkHeader.Size + chunkHeader.ChunkDataTotalSize + ChunkFooter.Size); }