yangle
2024-12-30 7f80be364af2ba22f8cf69b5e7f2ed771297ba2e
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using ICSharpCode.SharpZipLib.Zip;
 
namespace Top.Api.Util
{
    /// <summary>
    /// 异步API下载工具类。
    /// </summary>
    public abstract class AtsUtils
    {
        private const string CTYPE_OCTET = "application/octet-stream";
        private static Regex regex = new Regex("attachment;filename=\"([\\w\\-]+)\"", RegexOptions.Compiled);
 
        /// <summary>
        /// 通过HTTP GET方式下载文件到指定的目录。
        /// </summary>
        /// <param name="url">需要下载的URL</param>
        /// <param name="destDir">需要下载到的目录</param>
        /// <returns>下载后的文件</returns>
        public static string Download(string url, string destDir)
        {
            string file = null;
 
            try
            {
                WebUtils wu = new WebUtils();
                HttpWebRequest req = wu.GetWebRequest(url, "GET", null);
                HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
                if (CTYPE_OCTET.Equals(rsp.ContentType))
                {
                    file = Path.Combine(destDir, GetFileName(rsp.Headers["Content-Disposition"]));
                    using (System.IO.Stream rspStream = rsp.GetResponseStream())
                    {
                        int len = 0;
                        byte[] buf = new byte[8192];
                        using (FileStream fileStream = new FileStream(file, FileMode.OpenOrCreate))
                        {
                            while ((len = rspStream.Read(buf, 0, buf.Length)) > 0)
                            {
                                fileStream.Write(buf, 0, len);
                            }
                        }
                    }
                }
                else
                {
                    throw new TopException(wu.GetResponseAsString(rsp, Encoding.UTF8));
                }
            }
            catch (WebException e)
            {
                throw new TopException("isv.file-already-download", e.Message);
            }
            return file;
        }
 
        /// <summary>
        /// 解压gzip文件到指定的目录,目前只能解压gzip包里面只包含一个文件的压缩包。
        /// </summary>
        /// <param name="gzipFile">需要解压的gzip文件</param>
        /// <param name="destDir">需要解压到的目录(不能和压缩文件在同一个目录)</param>
        /// <returns>解压后的文件</returns>
        public static string Ungzip(string gzipFile, string destDir)
        {
            string destFile = Path.Combine(destDir, Path.GetFileName(gzipFile));
            using (System.IO.Stream output = File.Create(destFile))
            {
                using (System.IO.Stream input = new GZipStream(File.Open(gzipFile, FileMode.Open), CompressionMode.Decompress))
                {
                    int size = 0;
                    byte[] buf = new byte[8192];
                    while ((size = input.Read(buf, 0, buf.Length)) > 0)
                    {
                        output.Write(buf, 0, size);
                    }
                }
            }
 
            return destFile;
        }
 
        /// <summary>
        /// 解压zip文件到指定的目录。
        /// </summary>
        /// <param name="zipFile">需要解压的zip文件</param>
        /// <param name="destDir">需要解压到的目录</param>
        /// <returns>解压后的文件列表(不包含文件夹)</returns>
        public static List<string> Unzip(string zipFile, string destDir)
        {
            List<string> files = new List<string>();
 
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFile)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    if (theEntry.IsDirectory)
                    {
                        Directory.CreateDirectory(Path.Combine(destDir, theEntry.Name));
                        continue;
                    }
 
                    string fileName = Path.Combine(destDir, theEntry.Name);
                    using (FileStream streamWriter = File.Create(fileName))
                    {
                        int size = 0;
                        byte[] buf = new byte[8192];
                        while ((size = s.Read(buf, 0, buf.Length)) > 0)
                        {
                            streamWriter.Write(buf, 0, size);
                        }
                    }
                    files.Add(fileName);
                }
            }
 
            return files;
        }
 
        /// <summary>
        /// 检查指定文件的md5sum和指定的检验码是否一致。
        /// </summary>
        /// <param name="fileName">需要检验的文件</param>
        /// <param name="checkCode">已知的md5sum检验码</param>
        /// <returns>true/false</returns>
        public static bool CheckMd5sum(string fileName, string checkCode)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.Open))
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(stream);
 
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
 
                return sb.ToString().Equals(checkCode);
            }
        }
 
        private static string GetFileName(string contentDisposition)
        {
            Match match = regex.Match(contentDisposition);
            if (match.Success)
            {
                return match.Groups[1].ToString();
            }
            else
            {
                throw new TopException("Invalid response header format!");
            }
        }
    }
}