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.
67 lines
2.4 KiB
67 lines
2.4 KiB
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<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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|