zoukankan      html  css  js  c++  java
  • 文件下载+断点续传

    工具开发系列之:文件下载+断点续传

    2013-12-12 18:01 by Turbo Zhang, 325 阅读, 1 评论, 收藏编辑

    日常开发中总会遇到大量琐碎文件的Copy处理的问题,而如果文件较大的情况下,可能会遇到断电,远程Server崩溃等问题,于是断点续传问题就会提到议事上来。

    在这里分享一个自己用的DownLoad Tool 虽然细节有待商讨,暂起抛砖引玉之意:

    1. 新建控制台程序作为tool主程:
      1. 复制代码
        static void Main(string[] args) {
                    Console.WriteLine("{0:HH:mm:ss} Download tool start......",DateTime.Now);
                    DownLoadFunction.StartDownload();
                    Console.WriteLine("{0:HH:mm:ss} Download finished! Press <Enter> to exit.",DateTime.Now);
                    Console.ReadLine();
                }
        复制代码


         

    2. 相关Code:

           DownLoadFunction 作为下载主要类,实现下载功能,后续提供的FTP,HTTP等下载方式以工厂方式提供:

    复制代码
            public static Boolean StartDownload() {
                String srcPath = System.Configuration.ConfigurationManager.AppSettings["SourcePath"];
                String aimPath = System.Configuration.ConfigurationManager.AppSettings["TargetPath"];
                try {
                    IOHelper.WriteToXml(srcPath,aimPath);
                    LoadFile(srcPath, aimPath);
                    IOHelper.XmlDelete();
                    return true;
                } catch (Exception ex) {
                    Console.WriteLine("{0:HH:mm:ss} error:" + ex,DateTime.Now);
                }
                return false;
            }
    复制代码

    下面的方法为核心方法,首先建立远程下载目录文件,下载工程依次修改此文件相关条目状态。

    下载完成,相关条目状态设置为100%;
    文件夹下文件以递归方式实现(此处为出现性能问题的地区);

    如果下载过程中由于异常程序终止,下次下载时,程序发现上次记录过此目录,进行下载条目检查,状态未成100%的,则由此次进行下载,以实现断点下载。

    (如果想更加精细的实现“断点”,需要操作到file本身的属性,md5等各种校验)

    Code如下:

    复制代码
            #region private method
    
            private static void LoadFile(String srcPath, String aimPath) {
                Console.WriteLine("[Enter Path]: {0}",srcPath);
                try {
                    if (aimPath[aimPath.Length - 1] != System.IO.Path.DirectorySeparatorChar) {
                        aimPath += System.IO.Path.DirectorySeparatorChar;
                    }
                    if (!System.IO.Directory.Exists(aimPath)) {
                        System.IO.Directory.CreateDirectory(aimPath);
                    }
    
                    String[] fileList = System.IO.Directory.GetFileSystemEntries(srcPath);
    
                    foreach (String file in fileList) {
                        if (System.IO.Directory.Exists(file)) {
                            Console.WriteLine("[Enter Path]: {0}",file);
                            LoadFile(file, aimPath + System.IO.Path.GetFileName(file));
                        } else {
                            if (IOHelper.CheckDownloadState(file) != DownloadState.Finished) {
                                Console.WriteLine("[Download file]: {0}", file);
                                System.IO.File.Copy(file, aimPath + System.IO.Path.GetFileName(file), true);
                                IOHelper.UpdateDownlPer(file);
                            }
                        }
                    }
                } catch (Exception e) {
                    Console.WriteLine("{0:HH:mm:ss} error:" + e, DateTime.Now);
                }
    
            }
    
            #endregion
    复制代码

    对于下载条目文件的操作:

    复制代码
     public class IOHelper {
    
            #region Create directory
    
            public static void DirectoryCreate(String directoryName) {
                String createPath = Path.GetDirectoryName(directoryName);
                try {
                    if (!Directory.Exists(createPath)) { Directory.CreateDirectory(createPath); }
                    Console.WriteLine("{0:HH:mm:ss} directory {0} create successful!",directoryName);
                } catch (Exception ex) {
                    Console.WriteLine("{0:HH:mm:ss} Create directory error! message:"+ex);
                }
            }
    
            #endregion
    
            #region Config operate
            static StringBuilder sbXml = new StringBuilder();
            static readonly String xmlTargetPath = System.Configuration.ConfigurationManager.AppSettings["xmlPath"];
    
    
            public static void WriteToXml(String srcPath, String aimPath) {
                if (File.Exists(xmlTargetPath)) return;
    
                try {
                    if (aimPath[aimPath.Length - 1] != System.IO.Path.DirectorySeparatorChar) {
                        aimPath += System.IO.Path.DirectorySeparatorChar;
                    }
                    if (!System.IO.Directory.Exists(aimPath)) {
                        System.IO.Directory.CreateDirectory(aimPath);
                    }
    
                    String[] fileList = System.IO.Directory.GetFileSystemEntries(srcPath);
    
                    foreach (String file in fileList) {
                        if (System.IO.Directory.Exists(file)) {
                            WriteToXml(file, aimPath + System.IO.Path.GetFileName(file));
                        } else {
                            sbXml.AppendLine(file+"->0%");
                        }
                    }
    
                    File.WriteAllText(xmlTargetPath,sbXml.ToString(),Encoding.UTF8);
                } catch (Exception e) {
                    Console.WriteLine("{0:HH:mm:ss} write to xml error:" + e, DateTime.Now);
                }
    
            }
    
            public static void UpdateDownlPer(String line) {
                String[] lines = File.ReadAllLines(xmlTargetPath);
                for (int i = 0; i < lines.Length; i++) {
                    if (line == lines[i].Substring(0, lines[i].LastIndexOf("->"))) {
                        lines[i] = lines[i].Substring(0,lines[i].LastIndexOf("->")+2)+"100%";
                        break;
                    }
                }
                File.WriteAllLines(xmlTargetPath,lines,Encoding.UTF8);
            }
    
            public static DownloadState CheckDownloadState(String line) {
                DownloadState state=DownloadState.Start;
    
                String[] lines = File.ReadAllLines(xmlTargetPath);
                for (int i = 0; i < lines.Length; i++) {
                    if (line == lines[i].Substring(0, lines[i].LastIndexOf("->"))) {
                        if (lines[i].Substring(lines[i].LastIndexOf("->") + 2) == "100%") state = DownloadState.Finished;
                        else state = DownloadState.Start;
                        break;
                    }
                }
    
                return state;
            }
    
            public static void XmlDelete() {
                File.Delete(xmlTargetPath);
            }
            #endregion
        }
    复制代码
     public enum TaskState {
            Create, Processing, Error, Finished
        }

    XML:

    复制代码
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
      <appSettings>
        <add key="xmlPath" value="d:dbCopyconfigXml.txt"/>
        <add key="SourcePath" value="D:TestFile"/>
        <add key="TargetPath" value="D:dbCopy"/>
      </appSettings>
    </configuration>
    复制代码

    3.执行结果:

    下载条目列表:

     程序结果:

  • 相关阅读:
    数据库三级考试的随笔2.0
    数据库三级考试的随笔1.2
    数据库三级考试的随笔1.1
    数据库三级考试的随笔1.0
    陈贤文的第一次试水
    点分治总结
    Treap总结
    UML之二、建模元素(1)
    StarUML之九、starUML的一些特殊属性的说明
    UML之一、为什么需要UML?
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3472199.html
Copyright © 2011-2022 走看看