• .NET 断点上传


    ///
    /// 分段上传例子
    ///
    public class UpFileSingleTest
    {
    //我们定义Buffer为1000
    public const int BUFFER_COUNT = 1000;
    ///
    /// 将文件上传至服务器(本地),由于采取分段传输所以,
    /// 每段必须有一个起始位置和相对应该数据段的数据
    ///
    /// 服务器上文件地址
    /// 分段起始位置
    /// 每段的数据
    private void WriteToServer(string filePath, int startPositon, byte[] btArray)
    {
    FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate);
    using (fileStream)
    {
    //将流的位置设置在该段起始位置
    fileStream.Position = startPositon;
    //将该段数据通过FileStream写入文件中,每次写一段的数据,就好比是个水池,分段蓄水一样,直到蓄满为止
    fileStream.Write(btArray, 0, btArray.Length);
    }
    }
    ///

            /// 处理单独一段本地数据上传至服务器的逻辑,根据客户端传入的startPostion
            /// 和totalCount来处理相应段的数据上传至服务器(本地)
            /// 
            /// 本地需要上传的文件地址
            /// 服务器(本地)目标地址
            /// 该段起始位置
            /// 该段最大数据量
            public void UpLoadFileFromLocal(string localFilePath, string uploadFilePath, int startPostion, int totalCount)
            {
                //if(!File.Exists(localFilePath)){return;}
                //每次临时读取数据数
                int tempReadCount = 0;
                int tempBuffer = 0;
                //定义一个缓冲区数组
                byte[] bufferByteArray = new byte[BUFFER_COUNT];
                //定义一个FileStream对象
                FileStream fileStream = new FileStream(localFilePath, FileMode.Open);
                //将流的位置设置在每段数据的初始位置
                fileStream.Position = startPostion;
                using (fileStream)
                {
                    //循环将该段数据读出在写入服务器中
                    while (tempReadCount < totalCount)
                    {
    
                        tempBuffer = BUFFER_COUNT;
                        //每段起始位置+每次循环读取数据的长度
                        var writeStartPosition = startPostion + tempReadCount;
                        //当缓冲区的数据加上临时读取数大于该段数据量时,
                        //则设置缓冲区的数据为totalCount-tempReadCount 这一段的数据
                        if (tempBuffer + tempReadCount > totalCount)
                        {
                            //缓冲区的数据为totalCount-tempReadCount 
                            tempBuffer = totalCount - tempReadCount;
                            //读取该段数据放入bufferByteArray数组中
                            fileStream.Read(bufferByteArray, 0, tempBuffer);
                            if (tempBuffer > 0)
                            {
                                byte[] newTempBtArray = new byte[tempBuffer];
                                Array.Copy(bufferByteArray, 0, newTempBtArray, 0, tempBuffer);
                                //将缓冲区的数据上传至服务器
                                this.WriteToServer(uploadFilePath, writeStartPosition,
                                newTempBtArray);
                            }
    
                        }
                        //如果缓冲区的数据量小于该段数据量,并且tempBuffer=设定BUFFER_COUNT时,通过
                        //while 循环每次读取一样的buffer值的数据写入服务器中,直到将该段数据全部处理完毕
                        else if (tempBuffer == BUFFER_COUNT)
                        {
                            fileStream.Read(bufferByteArray, 0, tempBuffer);
                            this.WriteToServer(uploadFilePath, writeStartPosition,
                           bufferByteArray);
                        }
                        //通过每次的缓冲区数据,累计增加临时读取数
                        tempReadCount += tempBuffer;
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            UpFileSingleTest test = new UpFileSingleTest();
            FileInfo info = new FileInfo(@"G:\\Skyrim\20080204173728108.torrent");
            //取得文件总长度
            var fileLegth = info.Length;
            //假设将文件切成5段
            var divide = 5;
            //取到每个文件段的长度
            var perFileLengh = (int)fileLegth / divide;
            //表示最后剩下的文件段长度比perFileLengh小
            var restCount = (int)fileLegth % divide;
            //循环上传数据
            for (int i = 0; i < divide + 1; i++)
            {
                //每次定义不同的数据段,假设数据长度是500,那么每段的开始位置都是i*perFileLength
                var startPosition = i * perFileLengh;
                //取得每次数据段的数据量
                var totalCount = fileLegth - perFileLengh * i > perFileLengh ? perFileLengh :
               (int)(fileLegth - perFileLengh * i);
                //上传该段数据
                test.UpLoadFileFromLocal(@"G:\\Skyrim\\20080204173728108.torrent",
               @"G:\\Skyrim\\20080204173728109.torrent", startPosition, i == divide ? divide : totalCount);
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    在这里插入图片描述

  • 相关阅读:
    JAVA程序员和C程序员的差距在哪里?
    Cyanine5tetrazine(CAS号:1427705-31-4)结构式原理
    golang给函数参数设置默认值的几种方式(函数参数默认值)
    红日靶场(内网渗透)——2
    AI艺术的背后:详解文本生成图像模型【基于 VQ-VAE】
    计算机毕设 大数据上海租房数据爬取与分析可视化 -python 数据分析 可视化
    docker部署博客项目
    scrcpy用法大全
    深入理解操作系统-进程篇
    人类或小鼠染色体长度文件获取 hg19 mm10.chrom.sizes
  • 原文地址:https://blog.csdn.net/u013400314/article/details/126784808