之前项目中碰到,IIS上传大文件报错的问题,查了下是iis的设置问题,改吧改吧就好了,总感觉不爽,就自己写了一个大文件上传的activex,无奈,本人只有.net做的好点,就用.net写了一个,当然了,主要用的还是C#。

    怎么编写activex网上有很多,大家百度下,谷歌下,都出来了。

    我就把代码发出来,有要的可以研究下,注释什么的,还是很规范的。

Activex部分:

 

 

UploadActivexCtrl
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Drawing;
  5 using System.Data;
  6 using System.Globalization;
  7 using System.IO;
  8 using System.Linq;
  9 using System.Net;
 10 using System.Runtime.InteropServices;
 11 using System.Text;
 12 using System.Threading;
 13 using System.Threading.Tasks;
 14 using System.Web;
 15 using System.Windows.Forms;
 16 
 17 namespace MutifileUploadCtrl
 18 {
 19     [ComVisible(true)]
 20     [Guid("C4F9F24F-B860-4e79-945D-B9A281950C82")]
 21     [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
 22     public interface IUploadControlComEvents
 23     {
 24         [DispId(0x10000002)]
 25         void OnUploaded();
 26         [DispId(0x10000003)]
 27         void OnStatusChanged(String status);
 28     }
 29 //
 30 //     [Guid("4B3AE7D8-FB6A-4558-8A96-BF82B54F329C")]
 31 //     [ComVisible(true)]
 32 //     public interface IUploadControlComOjbect
 33 //     {
 34 //         [DispId(0x10000001)]
 35 //         void Upload(String filePaths, String saveFileNames);
 36 //     }
 37 
 38     [Guid("6e60ddbf-84fa-4d8f-b479-60879c861686"),
 39        ComSourceInterfaces(typeof(IUploadControlComEvents)),
 40        ClassInterface(ClassInterfaceType.AutoDual),
 41        // ComDefaultInterface(typeof(IUploadControlComOjbect)),
 42        // ClassInterface(ClassInterfaceType.None),
 43        ComVisible(true)]
 44      public class UploadControl : UserControl, IObjectSafety
 45      {
 46         [ComVisible(true)]
 47         public String SvrAddr { get; set; }
 48 
 49         [ComVisible(true)]
 50         public delegate void OnUploadedEventHanlder();
 51         public event OnUploadedEventHanlder OnUploaded;
 52 
 53         [ComVisible(true)]
 54         public delegate void OnStatusChangedEventHanlder(String status);
 55         public event OnStatusChangedEventHanlder OnStatusChanged;
 56 
 57         // 每次上传1M
 58         private const Int32 BUFFER_SIZE = 1024 * 1024;
 59 
 60         [ComVisible(true)]
 61         public void Upload(String filePaths, String saveFileNames)
 62         {
 63             var paths = filePaths.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);
 64             var fileNames = saveFileNames.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
 65 
 66             var factory = new TaskFactory();
 67 
 68             factory.StartNew(() =>
 69             {
 70                 var tasks = new List<Task>();
 71 
 72                 for (int index = 0; index < paths.Length; index++)
 73                 {
 74                     var path = paths[index];
 75                     var fileName = fileNames[index];
 76                     tasks.Add(factory.StartNew(() => UploadFile(path, fileName)));
 77                     //UploadFile(path, fileName);
 78                 }
 79 
 80                 Task.WaitAll(tasks.ToArray());
 81 
 82                 if (OnUploaded != null)
 83                 {
 84                     OnUploaded();
 85                 }
 86             });
 87         }
 88 
 89         [ComVisible(false)]
 90         private void UploadFile(String filePath, String saveFileName)
 91         {
 92             var fileName = Path.GetFileName(filePath);
 93 
 94             var stream = new FileStream(filePath, FileMode.Open);
 95 
 96             var fileData = new Byte[BUFFER_SIZE];
 97 
 98             var offset = 0;
 99 
100             var fileId = Guid.NewGuid().ToString();
101 
102             var totalSize = stream.Length;
103             var partCount = totalSize%BUFFER_SIZE == 0 ? totalSize/BUFFER_SIZE : totalSize/BUFFER_SIZE + 1;
104 
105             // 将文件流转写入网络流
106             var part = 1;
107             var response = "";
108             do
109             {
110                 var position = stream.Position;
111 
112                 offset = stream.Read(fileData, 0, fileData.Length);
113 
114                 if(offset == 0) break;
115 
116                 response = PostData(fileData, fileId, saveFileName, position, offset, part, (Int32)partCount);
117 
118                 if (OnStatusChanged != null)
119                 {
120                     OnStatusChanged(fileName + ";" + totalSize + ";" + position + ";" + offset);
121                 }
122 
123                 part++;
124             } while (offset > 0 && response == "ok");
125 
126             stream.Close();
127             stream.Dispose();
128         }
129        
130         [ComVisible(false)]
131         private String PostData(byte[] data, String fileId, String fileName, long position, Int32 size, Int32 part, Int32 partCount)
132         {
133             if (String.IsNullOrEmpty(SvrAddr)) return "";
134 
135             var paras = "?FileId=" + HttpUtility.UrlEncode(fileId) +
136                         "&PartNum=" + part +
137                         "&Position=" + position +
138                         "&FileSize=" + size +
139                         "&FileName=" + HttpUtility.UrlEncode(fileName) +
140                         "&PartCount=" + partCount;
141 
142             var request = (HttpWebRequest)WebRequest.Create(SvrAddr + paras);
143             request.Method = "POST";
144             request.ContentLength = data.Length;
145 
146             using (var stream = request.GetRequestStream())
147             {
148                 stream.Write(data, 0, data.Length);
149                 stream.Close();
150             }
151 
152             using (var myResponse = (HttpWebResponse) request.GetResponse())
153             {
154                 var reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
155                 return reader.ReadToEnd();
156             }
157         }
158 
159         #region 实现IObjectSafety接口
160         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
161         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
162         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
163         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
164         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
165 
166         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
167         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
168         private const int S_OK = 0;
169         private const int E_FAIL = unchecked((int)0x80004005);
170         private const int E_NOINTERFACE = unchecked((int)0x80004002);
171 
172         private bool _fSafeForScripting = true;
173         private bool _fSafeForInitializing = true;
174         //使ActiveX控件成为安全的控件
175         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
176         {
177             int Rslt = E_FAIL;
178             string strGUID = riid.ToString("B");
179             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
180             switch (strGUID)
181             {
182                 case _IID_IDispatch:
183                 case _IID_IDispatchEx:
184                     Rslt = S_OK;
185                     pdwEnabledOptions = 0;
186                     if (_fSafeForScripting == true)
187                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
188                     break;
189                 case _IID_IPersistStorage:
190                 case _IID_IPersistStream:
191                 case _IID_IPersistPropertyBag:
192                     Rslt = S_OK;
193                     pdwEnabledOptions = 0;
194                     if (_fSafeForInitializing == true)
195                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
196                     break;
197                 default:
198                     Rslt = E_NOINTERFACE;
199                     break;
200             }
201 
202             return Rslt;
203         }
204 
205         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
206         {
207             int Rslt = E_FAIL;
208 
209             string strGUID = riid.ToString("B");
210             switch (strGUID)
211             {
212                 case _IID_IDispatch:
213                 case _IID_IDispatchEx:
214                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
215                         Rslt = S_OK;
216                     break;
217                 case _IID_IPersistStorage:
218                 case _IID_IPersistStream:
219                 case _IID_IPersistPropertyBag:
220                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
221                         Rslt = S_OK;
222                     break;
223                 default:
224                     Rslt = E_NOINTERFACE;
225                     break;
226             }
227 
228             return Rslt;
229         }
230         #endregion
231     }
232 
233     [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
234     public interface IObjectSafety
235     {
236         [PreserveSig]
237         int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
238 
239         [PreserveSig]
240         int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask,
241                                       [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
242     }
243 
244 }

 

 

后来处理部分:

UploadHandler
  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Threading;
  6 using System.Web;
  7 
  8 namespace Server
  9 {
 10     public class ConfigFileEntry
 11     {
 12         public String FileId { get; set; }
 13         public String FileNameWithoutExtension { get; set; }
 14         public Int32 PartCount { get; set; }
 15         public String FileExtension { get; set; }
 16         public List<Int32> ReadyParts { get; set; }
 17     }
 18 
 19     /// <summary>
 20     /// Upload 的摘要说明
 21     /// </summary>
 22     public class Upload : IHttpHandler
 23     {
 24         private static Boolean _sign = false;
 25         const String CONFIG_FILE_EXTENSION = ".conf";
 26         private static String BASE_PATH;
 27         public void ProcessRequest(HttpContext context)
 28         {
 29             BASE_PATH = context.Server.MapPath("~/uploadfiles/");
 30 
 31             context.Response.ContentType = "text/plain";
 32             context.Response.HeaderEncoding = System.Text.Encoding.UTF8;
 33             context.Response.Charset = "utf-8";
 34 
 35             var fileId = HttpUtility.UrlDecode(context.Request["FileId"]);
 36             var fileName = HttpUtility.UrlDecode(context.Request["FileName"]);
 37             var position = int.Parse(context.Request["Position"]);
 38             var fileSize = int.Parse(context.Request["FileSize"]);
 39             var partNum = int.Parse(context.Request["PartNum"]);
 40             var fileExtension = Path.GetExtension(fileName);
 41             var partCount = int.Parse(context.Request["PartCount"]);
 42             var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
 43             var configFilePath = Path.Combine(BASE_PATH, fileNameWithoutExtension + CONFIG_FILE_EXTENSION);
 44 
 45             // 写入配置文件
 46             if (!File.Exists(configFilePath))
 47             {
 48                 WriteDataIntoConfigFile(configFilePath, fileId);
 49                 WriteDataIntoConfigFile(configFilePath, fileNameWithoutExtension);
 50                 WriteDataIntoConfigFile(configFilePath, partCount);
 51                 WriteDataIntoConfigFile(configFilePath, fileExtension);
 52             }
 53 
 54             var filePath = Path.Combine(BASE_PATH, fileNameWithoutExtension + "_" + partNum);
 55             
 56             WriteDataIntoDataFile(context, fileSize, filePath);
 57 
 58             // 启用检查线程,检测文件所有部分是否上传完成
 59             if (!_sign)
 60             {
 61                 _sign = true;
 62                 var thread = new Thread(MergeFile);
 63                 thread.Start();
 64             }
 65 
 66             // 判断写入文件大小是否等于上传大小
 67             var fileInfo = new FileInfo(filePath);
 68             
 69             if (fileInfo.Length == fileSize)
 70             {
 71                 // 把当前结果写入配置文件(表示当前part操作完成)
 72                 WriteDataIntoConfigFile(configFilePath, partNum);
 73             }
 74 
 75             context.Response.Write("ok");
 76         }
 77 
 78         /// <summary>
 79         /// 合并文件
 80         /// </summary>
 81         private void MergeFile()
 82         {
 83             do
 84             {
 85                 if (!_sign) break;
 86                 // 获取所有的配置文件
 87                 var configFiles = Directory.GetFiles(BASE_PATH, "*" + CONFIG_FILE_EXTENSION + "*");
 88 
 89                 foreach (var configFile in configFiles)
 90                 {
 91                     var fileName = Path.GetFileNameWithoutExtension(configFile);
 92                     var tempPath = Path.Combine(BASE_PATH, fileName + ".tmp");
 93                     // 移动文件
 94                     File.Copy(configFile, tempPath, true);
 95 
 96                     // 读取配置文件
 97                     var entry = ReadConfigFile(tempPath);
 98                     // 全部文件写入完成
 99                     if (entry.ReadyParts.Count == entry.PartCount)
100                     {
101                         // 删除配置文件
102                         File.Delete(configFile);
103                         // 合并文件
104                         CombineFiles(entry.FileNameWithoutExtension, entry.FileExtension, entry.ReadyParts);
105 
106                         // 删除临时文件
107                         File.Delete(tempPath);
108                     }
109                 }
110 
111                 Thread.Sleep(5000);
112             } while (true);
113 
114             
115             _sign = true;
116         }
117 
118         /// <summary>
119         /// 合并文件
120         /// </summary>
121         /// <param name="fileName"></param>
122         /// <param name="fileExtension"></param>
123         /// <param name="parts"></param>
124         private void CombineFiles(String fileName, String fileExtension, List<Int32> parts)
125         {
126             var stream = new FileStream(Path.Combine(BASE_PATH, fileName + fileExtension), FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
127             
128             for (var index = 1; index <= parts.Count; index ++)
129             {
130                 var dataFilePath = Path.Combine(BASE_PATH, fileName + "_" + index);
131                 var position = (Int32)stream.Length;
132                 var buffer = File.ReadAllBytes(dataFilePath);
133                 stream.Write(buffer, 0, buffer.Length);
134 
135                 File.Delete(dataFilePath);
136             }
137 
138             stream.Flush();
139             stream.Close();
140         }
141 
142         /// <summary>
143         /// 读取配置文件
144         /// </summary>
145         /// <param name="tempPath"></param>
146         /// <returns></returns>
147         private ConfigFileEntry ReadConfigFile(String tempPath)
148         {
149             var stream = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.Read);
150             var reader = new StreamReader(stream);
151 
152             var entry = new ConfigFileEntry();
153 
154             entry.FileId = reader.ReadLine();
155             entry.FileNameWithoutExtension = reader.ReadLine();
156             entry.PartCount = Int32.Parse(reader.ReadLine());
157             entry.FileExtension = reader.ReadLine();
158             entry.ReadyParts = new List<Int32>();
159 
160             while (!reader.EndOfStream)
161             {
162                 var str = reader.ReadLine();
163                 if (String.IsNullOrEmpty(str)) continue;
164 
165                 entry.ReadyParts.Add(Int32.Parse(str));
166             }
167 
168             reader.Close();
169             stream.Close();
170             reader.Dispose();
171             stream.Dispose();
172 
173             return entry;
174         }
175 
176         /// <summary>
177         /// 写入数据文件
178         /// </summary>
179         /// <param name="context"></param>
180         /// <param name="fileSize"></param>
181         /// <param name="filePath"></param>
182         private void WriteDataIntoDataFile(HttpContext context, int fileSize, string filePath)
183         {
184             var fileData = new byte[fileSize];
185             context.Request.InputStream.Read(fileData, 0, fileSize);
186 
187             var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
188             stream.Position = 0;
189             stream.Write(fileData, 0, fileSize);
190 
191             stream.Flush();
192 
193             stream.Close();
194             stream.Dispose();
195         }
196 
197         /// <summary>
198         /// 写入配置文件
199         /// </summary>
200         /// <param name="configFilePath"></param>
201         /// <param name="data"></param>
202         private void WriteDataIntoConfigFile(string configFilePath, Object data)
203         {
204             var stream = new FileStream(configFilePath, FileMode.Append, FileAccess.Write, FileShare.Write);
205             var writer = new StreamWriter(stream);
206 
207             writer.WriteLine(data);
208 
209             writer.Flush();
210             stream.Flush();
211 
212             writer.Close();
213             stream.Close();
214             writer.Dispose();
215             stream.Dispose();
216         }
217 
218         public bool IsReusable
219         {
220             get
221             {
222                 return false;
223             }
224         }
225     }
226 }

 

 

下载地址:百度网盘

posted on 2013-03-27 20:53  danny.fu  阅读(843)  评论(3编辑  收藏  举报