public class HttpListenerPostParaHelper
{
private HttpListenerContext request;
public HttpListenerPostParaHelper(HttpListenerContext request)
{
this.request = request;
}
private bool CompareBytes(byte[] source, byte[] comparison)
{
try
{
int count = source.Length;
if (source.Length != comparison.Length)
return false;
for (int i = 0; i < count; i++)
if (source[i] != comparison[i])
return false;
return true;
}
catch
{
return false;
}
}
private byte[] ReadLineAsBytes(Stream SourceStream)
{
var resultStream = new MemoryStream();
while (true)
{
int data = SourceStream.ReadByte();
resultStream.WriteByte((byte)data);
if (data == 10)
break;
}
resultStream.Position = 0;
byte[] dataBytes = new byte[resultStream.Length];
resultStream.Read(dataBytes, 0, dataBytes.Length);
return dataBytes;
}
//鱼 2022-06-23
private byte[] ReadBytes(Stream SourceStream, byte[] ends)
{
List bytes = new List();
while (true)
{
int data = SourceStream.ReadByte();
if (data == -1) break;
byte b = (byte)data;
bytes.Add(b);
if (bytes.Count >= ends.Length)
{
bool ok = true;
for (int i = 0; i < ends.Length; i++)
{
if (ends[i] != bytes[(bytes.Count - ends.Length + i)])
{
ok = false;
break;
}
}
if (ok) break;
}
}
return bytes.ToArray();
}
//鱼 2022-06-23 重写,解决换行符处理错误问题
public List GetHttpListenerPostValue()
{
try
{
List HttpListenerPostValueList = new List();
if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
{
string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray();
string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Trim();
byte[] ChunkBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
byte[] EndBoundary = Encoding.ASCII.GetBytes("--" + boundary);// "--\r\n");
byte[] rnrn = Encoding.ASCII.GetBytes("\r\n\r\n");
byte[] __rn = Encoding.ASCII.GetBytes("--\r\n");
byte[] rn = Encoding.ASCII.GetBytes("\r\n");
Stream SourceStream = request.Request.InputStream;
System.Text.RegularExpressions.Regex regexName = new System.Text.RegularExpressions.Regex("; ?name=\"([^\"]+)");
System.Text.RegularExpressions.Regex regexFileName = new System.Text.RegularExpressions.Regex("filename=\"([^\"]+)");
System.Text.RegularExpressions.Regex regexType = new System.Text.RegularExpressions.Regex("Content-Type: ([^\r]+)");
while (true)
{
byte[] currentChunk = ReadBytes(SourceStream, rn);
if (CompareBytes(currentChunk, __rn) || currentChunk.Length < 2)
{
break;
}
if (CompareBytes(currentChunk, rn) || CompareBytes(ChunkBoundary, currentChunk))
{
byte[] heads = ReadBytes(SourceStream, rnrn);
string str = Encoding.UTF8.GetString(heads);
byte[] datas = ReadBytes(SourceStream, EndBoundary);
HttpListenerPostValue data = new HttpListenerPostValue();
data.Datas = new byte[datas.Length - EndBoundary.Length - 2];
if (data.Datas.Length > 0)
Buffer.BlockCopy(datas, 0, data.Datas, 0, data.Datas.Length);
var m = regexName.Match(str);
data.Name = m.Success ? m.Groups[1].Value : "";
m = regexType.Match(str);
data.ContentType = m.Success ? m.Groups[1].Value : "";
m = regexFileName.Match(str);
data.FileName = m.Success ? m.Groups[1].Value : "";
HttpListenerPostValueList.Add(data);
}
}
}
return HttpListenerPostValueList;
}
catch (Exception ex)
{
throw new Exception(ex.StackTrace);
}
}
}
public class HttpListenerPostValue
{
public string ContentType { get; set; }
public string FileName { get; set; }
public string Name { get; set; }
public byte[] Datas { get; set; }
public override string ToString()
{
if (Datas == null || Datas.Length == 0) return "";
return System.Text.UTF8Encoding.UTF8.GetString(Datas);
}
}
以前在网上找的一段代码,后来发现有bug,会删除上传数据里的换行符,然后我就重写了下。
看到有网友说效率能不能提高下,我抽时间优化了下,不使用读字节了,简单测试效率是原来的3倍左右
///
/// 鱼 2022-12-12
/// 修改:2022-12-13
///
public class ReadStream : IDisposable
{
const int BufferSize = 64 * 1024;
private Stream SourceStream;
MemoryStream memoryStream = null;
int index = 0;
int length = 0;
byte[] datas = new byte[BufferSize];
public ReadStream(Stream SourceStream)
{
this.SourceStream = SourceStream;
}
public void Dispose()
{
if (memoryStream != null)
{
memoryStream.Close();
memoryStream = null;
}
}
int Find(int start, int end, byte[] bytes)
{
bool is_break;
for (int i = start; i <= end - bytes.Length; i++)
{
is_break = false;
for (int j = 0; j < bytes.Length; j++)
{
if (bytes[j] != datas[i + j])
{
is_break = true;
break;
}
}
if (!is_break)
{
return i;
}
}
return -1;
}
public byte[] ReadBytes(byte[] ends)
{
if (length == 0)
{
length = SourceStream.Read(datas, 0, datas.Length);
}
int endsLength = ends.Length;
while (true)
{
int i = Find(index, length, ends);
if (i == -1)
{
if (length > endsLength)
{
if (memoryStream == null)
{
memoryStream = new MemoryStream();
}
memoryStream.Write(datas, index, length - endsLength - index + 1);
Buffer.BlockCopy(datas, length - endsLength + 1, datas, 0, endsLength - 1);
index = 0;
length = endsLength - 1;
}
int len = SourceStream.Read(datas, length, datas.Length - length);
if (len == 0)
{
break;
}
length += len;
}
else if (memoryStream != null)
{
int dataLen = i + endsLength;
memoryStream.Write(datas, 0, dataLen);
Buffer.BlockCopy(datas, dataLen, datas, 0, length - dataLen);
index = 0;
length -= dataLen;
byte[] result = memoryStream.ToArray();
memoryStream.Close();
memoryStream = null;
return result;
}
else
{
int dataLen = i + endsLength - index;
byte[] result = new byte[dataLen];
Buffer.BlockCopy(datas, index, result, 0, dataLen);
index += dataLen;
return result;
}
}
return new byte[] { };
}
}
使用