C#文件操作集合六(文件上传、下载)

前言

        文件操作是开发过程中经常遇到的,如何创建文件、处理文件、保存文件以及读取文件这些工作是每一位开发都必须经历的。

这里围绕C#文件操作内容,我做了一次系统的梳理,主要包括以下几个模块:

1、文件内容操作:文件读写相关

2、文件检测

3、文件及目录创建和删除

4、文件移动

5、文件加密、解密

6、文件上传、下载

7、文件压缩相关

8、文件操作权限相关


一、小节摘要

本节实例讲述了C#实现的文件上传下载工具类。分享给大家供大家参考,具体如下:

1、上传(FileUpload控件)

2、上传(二进制流方式上传)

3、普通下载

4、分块下载

5、支持大文件、续传、速度限制、资源占用小的方式下载

二、详细内容

1、上传(FileUpload控件)

/// <summary>
/// 上传文件
/// </summary>
/// <param name="PosPhotoUpload">控件</param>
/// <param name="saveFileName">保存的文件名</param>
/// <param name="imagePath">保存的文件路径</param>
public string FileSc(FileUpload PosPhotoUpload, string saveFileName, string imagePath)
{
    string state = "";
    if (PosPhotoUpload.HasFile)
    {
        if (PosPhotoUpload.PostedFile.ContentLength / 1024 < 10240)
        {
            string MimeType = PosPhotoUpload.PostedFile.ContentType;
            if (String.Equals(MimeType, "image/gif") || String.Equals(MimeType, "image/pjpeg"))
            {
                string extFileString = System.IO.Path.GetExtension(PosPhotoUpload.PostedFile.FileName);
                PosPhotoUpload.PostedFile.SaveAs(HttpContext.Current.Server.MapPath(imagePath));
            }
            else
            {
                state = "上传文件类型不正确";
            }
        }
        else
        {
            state = "上传文件不能大于10M";
        }
    }
    else
    {
        state = "没有上传文件";
    }
    return state;
}

2、上传(二进制流方式上传)

/// <summary>
/// 上传文件
/// </summary>
/// <param name="binData">字节数组</param>
/// <param name="fileName">文件名</param>
/// <param name="fileType">文件类型</param>
public void SaveFile(byte[] binData, string fileName, string fileType)
{
    FileStream fileStream = null;
    MemoryStream m = new MemoryStream(binData);
    try
    {
        string savePath = HttpContext.Current.Server.MapPath("~/File/");
        if (!Directory.Exists(savePath))
        {
            Directory.CreateDirectory(savePath);
        }
        string File = savePath + fileName + fileType;
        fileStream = new FileStream(File, FileMode.Create);
        m.WriteTo(fileStream);
    }
    finally
    {
        m.Close();
        fileStream.Close();
    }
}

/// <summary>
/// 转换为字节数组
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>字节数组</returns>
public byte[] GetBinaryFile(string filename)
{
    if (File.Exists(filename))
    {
        FileStream Fsm = null;
        try
        {
            Fsm = File.OpenRead(filename);
            return this.ConvertStreamToByteBuffer(Fsm);
        }
        catch
        {
            return new byte[0];
        }
        finally
        {
            Fsm.Close();
        }
    }
    else
    {
        return new byte[0];
    }
}

/// <summary>
/// 流转化为字节数组
/// </summary>
/// <param name="theStream">流</param>
/// <returns>字节数组</returns>
public byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
{
    int bi;
    MemoryStream tempStream = new System.IO.MemoryStream();
    try
    {
        while ((bi = theStream.ReadByte()) != -1)
        {
            tempStream.WriteByte(((byte)bi));
        }
        return tempStream.ToArray();
    }
    catch
    {
        return new byte[0];
    }
    finally
    {
        tempStream.Close();
    }
}

调用方式:

byte[] by = GetBinaryFile("E:\\Hello.txt");

this.SaveFile(by,"Hello",".txt"); 

3、 普通下载

/// <summary>
/// 普通下载
/// </summary>
/// <param name="FileName">文件虚拟路径</param>
public static void DownLoadold(string FileName)
{
    string destFileName = MapPathFile(FileName);
    if (File.Exists(destFileName))
    {
        FileInfo fi = new FileInfo(destFileName);
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.Buffer = false;
        HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(destFileName), System.Text.Encoding.UTF8));
        HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
        HttpContext.Current.Response.ContentType = "application/octet-stream";
        HttpContext.Current.Response.WriteFile(destFileName);
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.End();
    }
}

4、分块下载

/// <summary>
/// 分块下载
/// </summary>
/// <param name="FileName">文件虚拟路径</param>
public static void DownLoad(string FileName)
{
    string filePath = MapPathFile(FileName);
    long chunkSize = 204800;             //指定块大小 
    byte[] buffer = new byte[chunkSize]; //建立一个200K的缓冲区 
    long dataToRead = 0;                 //已读的字节数   
    FileStream stream = null;
    try
    {
        //打开文件   
        stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        dataToRead = stream.Length;

        //添加Http头   
        HttpContext.Current.Response.ContentType = "application/octet-stream";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filePath)));
        HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());

        while (dataToRead > 0)
        {
            if (HttpContext.Current.Response.IsClientConnected)
            {
                int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));
                HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.Clear();
                dataToRead -= length;
            }
            else
            {
                dataToRead = -1; //防止client失去连接 
            }
        }
    }
    catch (Exception ex)
    {
        HttpContext.Current.Response.Write("Error:" + ex.Message);
    }
    finally
    {
        if (stream != null) stream.Close();
        HttpContext.Current.Response.Close();
    }
}

 分块下载是大文件下载的主要方式

5、支持大文件、续传、速度限制、资源占用小的方式下载


    /// <summary>
    ///  输出硬盘文件,提供下载 支持大文件、续传、速度限制、资源占用小
    /// </summary>
    /// <param name="_Request">Page.Request对象</param>
    /// <param name="_Response">Page.Response对象</param>
    /// <param name="_fileName">下载文件名</param>
    /// <param name="_fullPath">带文件名下载路径</param>
    /// <param name="_speed">每秒允许下载的字节数</param>
    /// <returns>返回是否成功</returns>
    public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed)
    {
        try
        {
            FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            BinaryReader br = new BinaryReader(myFile);
            try
            {
                _Response.AddHeader("Accept-Ranges", "bytes");
                _Response.Buffer = false;

                long fileLength = myFile.Length;
                long startBytes = 0;
                int pack = 10240;  //10K bytes
                int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1;

                if (_Request.Headers["Range"] != null)
                {
                    _Response.StatusCode = 206;
                    string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' });
                    startBytes = Convert.ToInt64(range[1]);
                }
                _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                if (startBytes != 0)
                {
                    _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                }

                _Response.AddHeader("Connection", "Keep-Alive");
                _Response.ContentType = "application/octet-stream";
                _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));

                br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;

                for (int i = 0; i < maxCount; i++)
                {
                    if (_Response.IsClientConnected)
                    {
                        _Response.BinaryWrite(br.ReadBytes(pack));
                        Thread.Sleep(sleep);
                    }
                    else
                    {
                        i = maxCount;
                    }
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                br.Close();
                myFile.Close();
            }
        }
        catch
        {
            return false;
        }
        return true;
    }

调用方式:

string FullPath=Server.MapPath("count.txt");

ResponseFile(this.Request,this.Response,"count.txt",FullPath,100); 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MarcoPro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值