自动更新,上传,下载

休息日,没事想放松下,感受一下大众瞩目的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();
            }

  
        }

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

原文地址:https://www.cnblogs.com/gavinhuang/p/3062651.html