public void Handle(FileChunkRequest message) { string filePath = Path.Combine(this.expanderSharedFiles, message.Type.ToString(), message.FileName); long fileSize = new FileInfo(filePath).Length; int chunkId = (int)(message.ChunkStart / message.ChunkSize); int chunks = (int)(fileSize / message.ChunkSize); this.log.Information("Request for file {0} chunk {1}/{2} for {3:N0} bytes", message.FileName, chunkId, chunks, message.ChunkSize); using (var fs = File.OpenRead(filePath)) { fs.Seek(message.ChunkStart, SeekOrigin.Begin); int bytesToRead = Math.Min(message.ChunkSize, (int)(fs.Length - message.ChunkStart)); if (bytesToRead <= 0) { return; } byte[] chunk = new byte[bytesToRead]; fs.Read(chunk, 0, chunk.Length); SendMessage(new FileChunkResponse { DownloadId = message.DownloadId, ChunkStart = message.ChunkStart, Chunk = chunk }); } }
/// <summary> /// Read a file chunk request` /// </summary> /// <param name="from">Origin</param> /// <param name="filename">Filename to read from</param> /// <param name="offset">Offset in the file</param> /// <param name="maxLength">Maximum chunk length</param> /// <returns>Number of bytes read</returns> public static int ReadFileChunkRequest(ReadOnlySpan <byte> from, out string filename, out uint offset, out uint maxLength) { FileChunkRequest header = MemoryMarshal.Cast <byte, FileChunkRequest>(from)[0]; int bytesRead = Marshal.SizeOf(header); // Read header offset = header.Offset; maxLength = header.MaxLength; // Read filename ReadOnlySpan <byte> unicodeFilename = from.Slice(bytesRead, (int)header.FilenameLength); filename = Encoding.UTF8.GetString(unicodeFilename); bytesRead += (int)header.FilenameLength; return(AddPadding(bytesRead)); }