• 自动更新,上传,下载


    休息日,没事想放松下,感受一下大众瞩目的LOL,可惜刚打开就提示需要更新,一看要更新好几百m,顿时郁闷之极,就为了玩个游戏,每个星期都得更新个半天.然后无聊了半天等待下载,发现闲着

    也是闲着,研究学习了,似乎LOL也是.net框架的,顺便就学习下自动更新吧. 1.自动更新,首先要比较服务端和客户端相关文件,具体比对哪些内容呢?修改时间,文件大小,文件内容等等,比对内容很多,这个时候就想到了用md5比较,具体实现:

     public static byte[] GetFileMd5(this FileInfo fileInfo)
            {
                using (var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var md5Provider = new MD5CryptoServiceProvider())
                    {
                        return md5Provider.ComputeHash(fs);
                    }
                }
            }

    2.文件md5后就可以比较两边的差异了,可以通过wcf连接,具体请参考
    http://www.cnblogs.com/gavinhuang/archive/2013/03/30/2991060.html创建服务.
    获取服务端md5,然后比较,具体实现:

    var needDownload = false;
    var localMd5 = new FileInfo(localFullPath).GetFileMd5();
    var updateClient = new AutoUpdateClient(EndpointName, endpointAddress);
    var remoteMd5 = updateClient.GetFileMd5(relativePath);
    needDownload = !localMd5.SequenceEqual(remoteMd5);

    服务端具体实现:

    public byte[] GetFileMd5(string fileName)
            {
                var beforeCount = Interlocked.Increment(ref _refreshQuests);
                var root = Settings.Default.VersionDirectory ;
                var fullPath = Path.Combine(Settings.Default.VersionDirectory, fileName);
                if (!File.Exists(fullPath))
                {
                    throw new FaultException<FileNotFoundFault>(new FileNotFoundFault
                    {
                        FileName = fileName,
                    });
                }
                var fileInfo = new FileInfo(fileName);
                var re = fileInfo.GetFileMd5();
                return re ;
            }
    
    public IAsyncResult BeginDownloadFile(string fileName, long position, int numBytes, AsyncCallback callback, object state)
            {
                var fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
                if (!File.Exists(fullPath))
                {
                    throw new FaultException<FileNotFoundFault>(new FileNotFoundFault
                    {
                        FileName = fileName,
                    });
                }
                return new FileTransferAsyncResult(fullPath, position, numBytes, callback, state);
            }
    
            public RemoteFileInfo EndDownloadFile(IAsyncResult ar)
            {
                return ((FileTransferAsyncResult)ar).EndInvoke();
            }

    同时定义FileTransferAsyncResult类继承Wintellect.Threading.AsyncProgModel.AsyncResult<RemoteFileInfo>

     public FileTransferAsyncResult(string fileName, long position, int numBytes, AsyncCallback callback, object state)
                : base(callback, state)
            {
                _buffer = new byte[numBytes];
                _stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous);
                _stream.Position = position;
                _stream.BeginRead(_buffer, 0, _buffer.Length, Wintellect.Threading.AsyncProgModel.AsyncResult<RemoteFileInfo>.GetAsyncCallbackHelper(), this);
            }
    
            protected override RemoteFileInfo OnCompleteOperation(IAsyncResult ar)
            {
                int bytesRead = _stream.EndRead(ar);
                long nextPosition = _stream.Position;
                long totalLength = _stream.Length;
                _stream.Close();
                return new RemoteFileInfo()
                {
                    Data = _buffer,
                    BytesLength = bytesRead,
                    NextPosition = nextPosition,
                    TotalLength = totalLength
                };
            }

    最后客户端连接

    private void DownLoad()
            {
                bool needDownload = true;
                var localPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test.txt");
                var client = new UpdateClient("netTcpBinding");
               
                int _downloadingRequests = 0;
                var bufferSize = 4096;
                if (File.Exists(localPath))
                {
                    var localMd5 = new FileInfo(localPath).GetFileMd5();
                    var remoteMd5 = client.GetFileMd5("Test.txt");
                    needDownload = !localMd5.SequenceEqual(remoteMd5);
                }
                if (needDownload)
                {
                    using (var fs = new FileStream(localPath, FileMode.Create, FileAccess.Write, FileShare.Write, bufferSize, FileOptions.Asynchronous))
                    {
                        long position = 0;
                        long writtenBytes = 0;
                        RemoteFileInfo info = null;
                        do
                        {
                            Interlocked.Increment(ref _downloadingRequests);
                            info = client.DownloadFile("Test.txt", 0, bufferSize);
    
                            Interlocked.Decrement(ref _downloadingRequests);
                            position = info.NextPosition;
                            fs.Write(info.Data, 0, info.BytesLength);
                            writtenBytes += info.BytesLength;
                        } while (info.BytesLength != position);
                    }
                    client.Close();
                }
    
      
            }

    这样自制的简易更新,或者上传,下载小程序做好了,当然还有许多地方可以优化比如进度条,比如同时更新多个等.

  • 相关阅读:
    [bzoj1280]卖猪
    [51nod1237]最大公约数之和V3
    [cf741C]Arpa’s overnight party and Mehrdad’s silent entering
    [bzoj1576]安全路径
    [bzoj1143]祭祀
    db_writer_processes默认大小
    oracle审计功能启动关闭
    db_writer_processes默认大小
    手机发博客
    第27课 .net程序破解
  • 原文地址:https://www.cnblogs.com/gavinhuang/p/3062651.html
Copyright © 2020-2023  润新知