using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace STcpHelper.Packet { public class STcpFileResPacket : ISTcpAsyncPacket { private string _path; public string FileName { get; private set; } public byte[] FileBinary { get; private set; } public STcpFileResPacket(string path) { this.FileName = Path.GetFileName(path); _path = path; } public STcpFileResPacket(byte[] dataBuffer, string path) { int cursor = 0; int nameLength = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor); cursor += sizeof(int); this.FileName = SEncoding.GetString(dataBuffer, cursor, nameLength); cursor += nameLength; int fileSize = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor); cursor += sizeof(int); this.FileBinary = new byte[fileSize]; Array.Copy(dataBuffer, cursor, this.FileBinary, 0, fileSize); File.WriteAllBytes(path + @$"\{FileName}", this.FileBinary); } public async Task Serialize() { byte[] name = SEncoding.GetBytes(this.FileName); byte[] nameLength = SBufferHelper.ConvertDataLengthToBuffer(name.Length); byte[] data = await ReadFileAsync(_path); byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length); int dataSize = STcpPacketHeader.GetDataSize(name, nameLength, data, dataLength); // 4bytes header STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_FILE, dataSize); // [heaer][2byte name size][n bytes name][2bytes file size][n bytes string] return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), nameLength, name, dataLength, data); } private async Task ReadFileAsync(string path) { using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024, useAsync: true)) { byte[] buffer = new byte[stream.Length]; await stream.ReadAsync(buffer, 0, (int)stream.Length); return buffer; } } } }