You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.4 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
2 years ago
using STcpHelper.Utility;
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<byte[]> 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<byte[]> 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;
}
}
}
}