C# 上传文件

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;


namespace Upload
{
    public class AdvertisementSource : IDisposable
    {
        HttpListener httpListener;
        bool stopped;

        #region 构造和析构

        // == 

        #region IDisposable

        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        int disposedFlag;

        ~AdvertisementSource()
        {
            Dispose(false);
        }

        ///<summary>
        ///释放所占用的资源
        ///</summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ///   <summary> 
        ///  获取该对象是否已经被释放
        ///   </summary> 
        [System.ComponentModel.Browsable(false)]
        public bool IsDisposed
        {
            get { return disposedFlag != 0; }
        }

        #endregion

        protected virtual void Dispose(bool disposing)
        {
            if (System.Threading.Interlocked.Increment(ref disposedFlag) != 1) return;
            if (disposing)
            {
                httpListener.Stop();
            }

            // 在这里编写非托管资源释放代码 
        }

        #endregion

        public void Initialize(int port = 8080)
        {
            try
            {
                httpListener = new HttpListener();
                httpListener.Prefixes.Add($"http://*:{port}/upload/");
                httpListener.Start();
                httpListener.BeginGetContext(GetHttpContextCallback, null);
            }
            catch (Exception e)
            {
                Console.WriteLine($"{port}被占用");
            }
        }

        public void GetHttpContextCallback(IAsyncResult iar)
        {
            if (stopped) return;
            var context = httpListener.EndGetContext(iar);
            httpListener.BeginGetContext(GetHttpContextCallback, null);
            //string endPoint = context.Request.RemoteEndPoint.ToString();
            //int spIndex = endPoint.IndexOf(":");
            //endPoint = endPoint.Substring(0, spIndex);

            using (HttpListenerResponse response = context.Response)
            {
                //get 的方式在如下解析即可得到客户端参数及值 
                // string userName = context.Request.QueryString["userName"];
                // string password = context.Request.QueryString["password"];
                // string suffix = context.Request.QueryString["suffix"];
                // string adType = context.Request.QueryString["adtype"]; // 文字,图片,视频 


                if (!context.Request.HasEntityBody) // 无数据 
                {
                    response.StatusCode = 403;
                    return;
                }

                //post 的方式有文件上传的在如下解析即可得到客户端参数及值 
                HttpListenerRequest request = context.Request;
                if (request.ContentType.Length > 20 && string.Compare(request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
                {
                    List<Values> lst = new List<Values>();
                    Encoding Encoding = request.ContentEncoding;
                    string[] values = request.ContentType.Split(';').Skip(1).ToArray();
                    string boundary = string.Join(";", values).Replace("boundary=", "").Trim();
                    byte[] ChunkBoundary = Encoding.GetBytes("--" + boundary + "\r\n");
                    byte[] EndBoundary = Encoding.GetBytes("--" + boundary   + "--\r\n");
                    Stream SourceStream = request.InputStream;
                    var resultStream = new MemoryStream();
                    bool CanMoveNext = true;
                    Values data = null;
                    while (CanMoveNext)
                    {
                        byte[] currentChunk = ReadLineAsBytes(SourceStream);
                        if (!Encoding.GetString(currentChunk).Equals("\r\n"))
                            resultStream.Write(currentChunk, 0, currentChunk.Length);
                        if (CompareBytes(ChunkBoundary, currentChunk))
                        {
                            byte[] result = new byte[resultStream.Length - ChunkBoundary.Length];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);
                            CanMoveNext = true;
                            if (result.Length > 0)
                                data.datas = result;
                            data = new Values();
                            lst.Add(data);
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        }
                        else if (Encoding.GetString(currentChunk).Contains("Content-Disposition"))
                        {
                            byte[] result = new byte[resultStream.Length - 2];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);

                            var strings = Encoding.GetString(result).Split('=');
                            data.fileName = strings[strings.Length - 1].Replace("\"","");
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        }
                        else if (Encoding.GetString(currentChunk).Contains("Content-Type"))
                        {
                            CanMoveNext = true;
                            data.type = 1;
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        }
                        else if (CompareBytes(EndBoundary, currentChunk))
                        {
                            byte[] result = new byte[resultStream.Length - EndBoundary.Length - 2];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);
                            data.datas = result;
                            resultStream.Dispose();
                            CanMoveNext = false;
                        }
                    }

                    foreach (var key in lst)
                    {
                        if (key.type == 0)
                        {
                            //参数暂不做处理
                        }

                        if (key.type == 1)
                        {
                            FileStream fs = new FileStream(System.Web.HttpUtility.UrlDecode(key.fileName), FileMode.Create);
                            fs.Write(key.datas, 0, key.datas.Length);
                            fs.Close();
                            fs.Dispose();
                        }
                    }
                }

                response.ContentType = "text/html;charset=utf-8";
                try
                {
                    using (System.IO.Stream output = response.OutputStream)
                    using (StreamWriter writer = new StreamWriter(output, Encoding.UTF8))
                        writer.WriteLine("接收完成!");
                }
                catch
                {
                }

                response.Close();
            }
        }

        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;
        }

        bool CompareBytes(byte[] source, byte[] comparison)
        {
            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;
        }

        public class Values
        {
            public int type = 0; // 0参数,1文件 
            public string fileName;
            public byte[] datas;
        }
    }
}

目前存在的问题:1、无法上传中文名字的文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值