您的位置:

首页 >

5060官方网址大全 >

5060官方网址大全:基于.Net中的协变与逆变的深入分析 >

5060官方网址大全:基于.Net中的协变与逆变的深入分析

2016-02-03 12:26:32

分类:5060官方网址大全

关于协变和逆变要从面向对象继承说起。继承关系是指子类和父类之间的关系;子类从父类继承所以子类的实例也就是父类的实例。比如说Animal是父类,Dog是从Animal继承的子类;如果一个对象的类型是Dog,那么他必然是Animal。协变逆变正是利用继承关系 对不同参数类型或返回值类型 的委托或者泛型接口之间做转变。我承认这句话很绕,如果你也觉得绕不妨往下看看。如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变。如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变。由子类向父类方向转变是协变 协变用于返回值类型用out关键字由父类向子类方向转变是逆变 逆变用于方法的参数类型用in关键字协变逆变中的协逆是相对于继承关系的继承链方向而言的。一. 数组的协变:复制代码 代码如下:Animal[] animalArray = new Dog[]{};上面一行代码是合法的,声明的数组数据类型是Animal,而实际上赋值时给的是Dog数组;每一个Dog对象都可以安全的转变为Animal。Dog向Animal方法转变是沿着继承链向上转变的所以是协变二. 委托中的协变和逆变1.委托中的协变复制代码 代码如下://委托定义的返回值是Animal类型是父类public delegate Animal GetAnimal();//委托方法实现中的返回值是Dog,是子类static Dog GetDog(){return new Dog();}//GetDog的返回值是Dog, Dog是Animal的子类;返回一个Dog肯定就相当于返回了一个Animal;所以下面对委托的赋值是有效的GetAnimal getMethod = GetDog;2.委托中的逆变复制代码 代码如下://委托中的定义参数类型是Dogpublic delegate void FeedDog(Dog target);//实际方法中的参数类型是Animalstatic void FeedAnimal(Animal target){}// FeedAnimal是FeedDog委托的有效方法,因为委托接受的参数类型是Dog;而FeedAnimal接受的参数是animal,Dog是可以隐式转变成Animal的,所以委托可以安全的的做类型转换,正确的执行委托方法;FeedDog feedDogMethod = FeedAnimal;定义委托时的参数是子类,实际上委托方法的参数是更宽泛的父类Animal,是父类向子类方向转变,是逆变三. 泛型委托的协变和逆变:1. 泛型委托中的逆变如下委托声明:复制代码 代码如下:public delegate void Feed<in T>(T target);Feed委托接受一个泛型类型T,注意在泛型的尖括号中有一个in关键字,这个关键字的作用是告诉编译器在对委托赋值时类型T可能要做逆变复制代码 代码如下://先声明一个T为Animal的委托Feed<Animal> feedAnimalMethod = a=>Console.WriteLine(“Feed animal lambda”);//将T为Animal的委托赋值给T为Dog的委托变量,这是合法的,因为在定义泛型委托时有in关键字,如果把in关键字去掉,编译器会认为不合法Feed<Dog> feedDogMethod = feedAnimalMethod;2. 泛型委托中的协变如下委托声明:复制代码 代码如下:public delegate T Find<out T>();Find委托要返回一个泛型类型T的实例,在泛型的尖括号中有一个out关键字,该关键字表明T类型是可能要做协变的复制代码 代码如下://声明Find<Dog>委托Find<Dog> findDog = ()=>new Dog();//声明Find<Animal>委托,并将findDog赋值给findAnimal是合法的,类型T从Dog向Animal转变是协变Find<Animal> findAnimal = findDog;四. 泛型接口中的协变和逆变:泛型接口中的协变逆变和泛型委托中的非常类似,只是将泛型定义的尖括号部分换到了接口的定义上。1.泛型接口中的逆变如下接口定义:复制代码 代码如下:public interface IFeedable<in T>{void Feed(T t);}接口的泛型T之前有一个in关键字,来表明这个泛型接口可能要做逆变如下泛型类型FeedImp<T>,实现上面的泛型接口;需要注意的是协变和逆变关键字in,out是不能在泛型类中使用的,编译器不允许复制代码 代码如下:public class FeedImp<T>:IFeedable<T>{    public void Feed(T t){        Console.WriteLine(“Feed Animal”);    }}来看一个使用接口逆变的例子:复制代码 代码如下:IFeedable<Dog> feedDog = new FeedImp<Animal>();上面的代码将FeedImp<Animal>类型赋值给了IFeedable<Dog>的变量;Animal向Dog转变了,所以是逆变2.泛型接口中的协变如下接口的定义:复制代码 代码如下:public interface IFinder<out T>{    T Find();}泛型接口的泛型T之前用了out关键字来说明此接口是可能要做协变的;如下泛型接口实现类复制代码 代码如下:public class Finder<T>:IFinder<T> where T:new(){    public T Find(){        return new T();    }}//使用协变,IFinder的泛型类型是Animal,但是由于有out关键字,我可以将Finder<Dog>赋值给它IFinder<Animal> finder = new Finder<Dog>();协变和逆变的概念不太容易理解,可以通过实际代码思考理解。这么绕的东西到底有用吗?答案是肯定的,通过协变和逆变可以更好的复用代码。复用是软件开发的一个永恒的追求。

今天JS练手的时候,想封装一个发送AJAX请求的对象,当然,是想要兼容全浏览器的。代码如下: 复制代码 代码如下: var Ajax = { xhr: null, callback: null, XMLHttp: function() { var xmlhttp; //标准浏览器 if(window.XMLHttpRequest) { try { xmlhttp = new XMLHttpRequest(); } catch(e) { alert('Unknown Ajax Error'); //console.log('Unknown Ajax Error'); } } //IE浏览器 else { if(window.ActiveXObject) { try { xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { try { xmlhttp = new ActiveXObject('MSXML2.XMLHTTP'); } catch(e) { alert('Unknown Ajax Error'); //console.log('Unknown Ajax Error'); } } } } return xmlhttp; }, connect: function(paramsObj) { var PO = paramsObj; //判断传参合法性 if(!(PO instanceof Object)) { alert('Ajax params illegal'); //console.log('Ajax params illegal'); return false; } else if(!(PO.url&&PO.method&&PO.callback)) { return false; } //初始化内部参数 this.xhr = this.XMLHttp(); this.callback = PO.callback; //遍历params对象并生成url参数 var requestParams = ''; if(PO.params) { for(key in Po.params) { requestParams += '&' + key + '=' + params[key]; } requestParams = requestParams.substr(1); } //发起Ajax请求 try { var xhr = this.xhr; xhr.onreadystatechange = this.response; //POST请求处理 if(PO.method.toLowerCase()=='post') { xhr.open('POST',PO.url,true); xhr.send(requestParams); } //GET请求处理 else if(PO.method.toLowerCase()=='get') { xhr.open('GET',PO.url+'?'+requestParams,true); xhr.send(null); } } catch(e) { this.callback(null,-1); } }, response: function() { // 此段代码在全浏览器下测试通过 // if(Ajax.xhr.readyState==4) { // if(Ajax.xhr.status=='200') { // Ajax.callback(Ajax.xhr.responseText); // } // else { // Ajax.callback(null,Ajax.xhr.status); // } // } // // 下面的代码在IE下失效(无报错,请求有相应,却没有返回结果),其它浏览器无此问题 if(this.readyState==4) { if(this.status=='200') { Ajax.callback(this.responseText); } else { Ajax.callback(null,this.status); } } } }; //Ajax实例 Ajax.connect({ url: 'test.html', method: 'GET', callback: function(data,err) { if(data!=null) { alert(data); // console.log(data); } else { alert(err); // console.log(err); } } }); 问题描述: 大家看一下我代码中有一块注释掉的代码,那块代码是在全浏览器下测试通过的。而没有注释掉的代码是有问题的代码,具体表现: 在Chrome,Firefox,Opera,Safari下测试通过,在IE6、7(IE8+没有测试)下的表现是:没有报错,也没有返回结果。 对比上下两块代码的不同,我想有两个可能,一个是this指向的问题,一个是IE下onreadystatechange函数执行的上下文环境有区别于其它浏览器。但是现在又无法确定问题,IE6、7下的JS调试又挺困难的(试了firebug-lite,但是没有想象中的好用,而且这个Ajax对象在firebug-lite下调用却成功了,有点糊涂) 解决过程: 其实测试方法很简单。主要是头脑一发热没想到,吃了个饭回来就恍然大悟。 其实JS在处理this指向不明的问题的时候,可以尝试使用this instanceof Object这类判断去了解它指向的是一个什么类型的变量。而对于判断是否为全局调用,则可以使用this===window。在这里我用的就是这个方法。 在代码出现问题的那一块,我们可以试着插入一段: alert(this instanceof Object); 结果发现,在IE6下,返回为false!一目了然!在IE下才可能出现如此诡异的返回值!证明什么?也就是说函数的执行上下文并非是对象!如此一来,在IE下就只能想到window对象了,要知道IE向来都是奇葩。你们标准浏览器说window对象是对象,我就偏不认。你还在怀疑我的看法?那何不试试? alert(this===window); 结果是true!怎么样?没话说了吧?所以这样,问题就明朗了: 在IE下,AJAX请求得到响应后,回调函数onreadystatechange是在全局环境下被调用的。而在标准浏览器下,其执行上下文是XMLHttpRequest对象。故造成了我这次的“事故”。

复制代码 代码如下:using System;  using System.Collections.Generic;  using System.Text;  using System.Runtime.InteropServices;  using System.Collections;  /** Convert PDF to Image Format(JPEG) using Ghostscript API convert a pdf to jpeg using ghostscript command line: gswin32c -q -dQUIET -dPARANOIDSAFER  -dBATCH -dNOPAUSE  -dNOPROMPT -dMaxBitmap=500000000 -dFirstPage=1 -dAlignToPixels=0 -dGridFitTT=0 -sDEVICE=jpeg -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r100x100 -sOutputFile=output.jpg test.pdf see also:http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/ and: http://www.codeproject.com/KB/cs/GhostScriptUseWithCSharp.aspx Note:copy gsdll32.dll to system32 directory before using this ghostscript wrapper.  *   */  namespace ConvertPDF  {      /// <summary>      ///       /// Class to convert a pdf to an image using GhostScript DLL      /// Credit for this code go to:Rangel Avulso      /// i only fix a little bug and refactor a little      /// http://www.hrangel.com.br/index.php/2006/12/04/converter-pdf-para-imagem-jpeg-em-c/      /// </summary>      /// <seealso cref="http://www.hrangel.com.br/index.php/2006/12/04/converter-pdf-para-imagem-jpeg-em-c/"/>      class PDFConvert      {          #region GhostScript Import          /// <summary>Create a new instance of Ghostscript. This instance is passed to most other gsapi functions. The caller_handle will be provided to callback functions.          ///  At this stage, Ghostscript supports only one instance. </summary>          /// <param name="pinstance"></param>          /// <param name="caller_handle"></param>          /// <returns></returns>          [DllImport("gsdll32.dll", EntryPoint="gsapi_new_instance")]          private static extern int gsapi_new_instance (out IntPtr pinstance, IntPtr caller_handle);          /// <summary>This is the important function that will perform the conversion</summary>          /// <param name="instance"></param>          /// <param name="argc"></param>          /// <param name="argv"></param>          /// <returns></returns>          [DllImport("gsdll32.dll", EntryPoint="gsapi_init_with_args")]          private static extern int gsapi_init_with_args (IntPtr instance, int argc, IntPtr argv);          /// <summary>          /// Exit the interpreter. This must be called on shutdown if gsapi_init_with_args() has been called, and just before gsapi_delete_instance().           /// </summary>          /// <param name="instance"></param>          /// <returns></returns>          [DllImport("gsdll32.dll", EntryPoint="gsapi_exit")]          private static extern int gsapi_exit (IntPtr instance);          /// <summary>          /// Destroy an instance of Ghostscript. Before you call this, Ghostscript must have finished. If Ghostscript has been initialised, you must call gsapi_exit before gsapi_delete_instance.           /// </summary>          /// <param name="instance"></param>          [DllImport("gsdll32.dll", EntryPoint="gsapi_delete_instance")]          private static extern void gsapi_delete_instance (IntPtr instance);          #endregion          #region Variables          private string _sDeviceFormat;          private int _iWidth;          private int _iHeight;          private int _iResolutionX;          private int _iResolutionY;          private int _iJPEGQuality;          private Boolean _bFitPage;          private IntPtr _objHandle;          #endregion          #region Proprieties          public string OutputFormat          {              get { return _sDeviceFormat; }              set { _sDeviceFormat = value; }          }          public int Width          {              get { return _iWidth; }              set { _iWidth = value; }          }          public int Height          {              get { return _iHeight; }              set { _iHeight = value; }          }          public int ResolutionX          {              get { return _iResolutionX; }              set { _iResolutionX = value; }          }          public int ResolutionY          {              get { return _iResolutionY; }              set { _iResolutionY = value; }          }          public Boolean FitPage          {              get { return _bFitPage; }              set { _bFitPage = value; }          }          /// <summary>Quality of compression of JPG</summary>          public int JPEGQuality          {              get { return _iJPEGQuality; }              set { _iJPEGQuality = value; }          }          #endregion          #region Init          public PDFConvert(IntPtr objHandle)          {              _objHandle = objHandle;          }          public PDFConvert()          {              _objHandle = IntPtr.Zero;          }          #endregion          private byte[] StringToAnsiZ(string str)          {              //' Convert a Unicode string to a null terminated Ansi string for Ghostscript.              //' The result is stored in a byte array. Later you will need to convert              //' this byte array to a pointer with GCHandle.Alloc(XXXX, GCHandleType.Pinned)              //' and GSHandle.AddrOfPinnedObject()              int intElementCount;              int intCounter;              byte[] aAnsi;              byte bChar;              intElementCount = str.Length;              aAnsi = new byte[intElementCount+1];              for(intCounter = 0; intCounter < intElementCount;intCounter++)              {                  bChar = (byte)str[intCounter];                  aAnsi[intCounter] = bChar;              }              aAnsi[intElementCount] = 0;              return aAnsi;          }          /// <summary>Convert the file!</summary>          public void Convert(string inputFile,string outputFile,              int firstPage, int lastPage, string deviceFormat, int width, int height)          {              //Avoid to work when the file doesn't exist              if (!System.IO.File.Exists(inputFile))              {                  System.Windows.Forms.MessageBox.Show(string.Format("The file :'{0}' doesn't exist",inputFile));                  return;              }              int intReturn;              IntPtr intGSInstanceHandle;              object[] aAnsiArgs;              IntPtr[] aPtrArgs;              GCHandle[] aGCHandle;              int intCounter;              int intElementCount;              IntPtr callerHandle;              GCHandle gchandleArgs;              IntPtr intptrArgs;              string[] sArgs = GetGeneratedArgs(inputFile,outputFile,                  firstPage, lastPage, deviceFormat, width, height);              // Convert the Unicode strings to null terminated ANSI byte arrays              // then get pointers to the byte arrays.              intElementCount = sArgs.Length;              aAnsiArgs = new object[intElementCount];              aPtrArgs = new IntPtr[intElementCount];              aGCHandle = new GCHandle[intElementCount];              // Create a handle for each of the arguments after               // they've been converted to an ANSI null terminated              // string. Then store the pointers for each of the handles              for(intCounter = 0; intCounter< intElementCount; intCounter++)              {                  aAnsiArgs[intCounter] = StringToAnsiZ(sArgs[intCounter]);                  aGCHandle[intCounter] = GCHandle.Alloc(aAnsiArgs[intCounter], GCHandleType.Pinned);                  aPtrArgs[intCounter] = aGCHandle[intCounter].AddrOfPinnedObject();              }              // Get a new handle for the array of argument pointers              gchandleArgs = GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned);              intptrArgs = gchandleArgs.AddrOfPinnedObject();              intReturn = gsapi_new_instance(out intGSInstanceHandle, _objHandle);              callerHandle = IntPtr.Zero;              try              {                  intReturn = gsapi_init_with_args(intGSInstanceHandle, intElementCount, intptrArgs);              }              catch (Exception ex)              {                  //System.Windows.Forms.MessageBox.Show(ex.Message);              }              finally              {                  for (intCounter = 0; intCounter < intReturn; intCounter++)                  {                      aGCHandle[intCounter].Free();                  }                  gchandleArgs.Free();                  gsapi_exit(intGSInstanceHandle);                  gsapi_delete_instance(intGSInstanceHandle);              }          }          private string[] GetGeneratedArgs(string inputFile, string outputFile,              int firstPage, int lastPage, string deviceFormat, int width, int height)          {              this._sDeviceFormat = deviceFormat;              this._iResolutionX = width;              this._iResolutionY = height;              // Count how many extra args are need - HRangel - 11/29/2006, 3:13:43 PM              ArrayList lstExtraArgs = new ArrayList();              if ( _sDeviceFormat=="jpg" && _iJPEGQuality > 0 && _iJPEGQuality < 101)                  lstExtraArgs.Add("-dJPEGQ=" + _iJPEGQuality);              if (_iWidth > 0 && _iHeight > 0)                  lstExtraArgs.Add("-g" + _iWidth + "x" + _iHeight);              if (_bFitPage)                  lstExtraArgs.Add("-dPDFFitPage");              if (_iResolutionX > 0)              {                  if (_iResolutionY > 0)                      lstExtraArgs.Add("-r" + _iResolutionX + "x" + _iResolutionY);                  else                      lstExtraArgs.Add("-r" + _iResolutionX);              }              // Load Fixed Args - HRangel - 11/29/2006, 3:34:02 PM              int iFixedCount = 17;              int iExtraArgsCount = lstExtraArgs.Count;              string[] args = new string[iFixedCount + lstExtraArgs.Count];              /*             // Keep gs from writing information to standard output         "-q",                              "-dQUIET",         "-dPARANOIDSAFER", // Run this command in safe mode         "-dBATCH", // Keep gs from going into interactive mode         "-dNOPAUSE", // Do not prompt and pause for each page         "-dNOPROMPT", // Disable prompts for user interaction                    "-dMaxBitmap=500000000", // Set high for better performance         // Set the starting and ending pages         String.Format("-dFirstPage={0}", firstPage),         String.Format("-dLastPage={0}", lastPage),            // Configure the output anti-aliasing, resolution, etc         "-dAlignToPixels=0",         "-dGridFitTT=0",         "-sDEVICE=jpeg",         "-dTextAlphaBits=4",         "-dGraphicsAlphaBits=4",             */              args[0]="pdf2img";//this parameter have little real use              args[1]="-dNOPAUSE";//I don't want interruptions              args[2]="-dBATCH";//stop after              //args[3]="-dSAFER";              args[3] = "-dPARANOIDSAFER";              args[4]="-sDEVICE="+_sDeviceFormat;//what kind of export format i should provide              args[5] = "-q";              args[6] = "-dQUIET";              args[7] = "-dNOPROMPT";              args[8] = "-dMaxBitmap=500000000";              args[9] = String.Format("-dFirstPage={0}", firstPage);              args[10] = String.Format("-dLastPage={0}", lastPage);              args[11] = "-dAlignToPixels=0";              args[12] = "-dGridFitTT=0";              args[13] = "-dTextAlphaBits=4";              args[14] = "-dGraphicsAlphaBits=4";              //For a complete list watch here:              //http://pages.cs.wisc.edu/~ghost/doc/cvs/Devices.htm              //Fill the remaining parameters              for (int i=0; i < iExtraArgsCount; i++)              {                  args[15+i] = (string) lstExtraArgs[i];              }              //Fill outputfile and inputfile              args[15 + iExtraArgsCount] = string.Format("-sOutputFile={0}",outputFile);              args[16 + iExtraArgsCount] = string.Format("{0}",inputFile);              return args;          }          public void pdf2jpgTest()          {                          this.Convert(@"C://tmp//pdfimg//test1.pdf",@"C://tmp//pdfimg//out.jpg",1,1,"jpeg",100,100);              //this.Convert(@"C://tmp//pdfimg//test.pdf", @"C://tmp//pdfimg//out2.jpg", 291, 291, "jpeg", 800, 800);          }      }  }  测试WinForm:可以采用下面的方式测试调用上面的功能,如:复制代码 代码如下: PDFConvert convertor = new PDFConvert(); convertor.pdf2jpgTest(); 复制代码 代码如下:using System;  using System.Collections.Generic;  using System.ComponentModel;  using System.Data;  using System.Drawing;  using System.Linq;  using System.Text;  using System.Windows.Forms;  using ConvertPDF;  namespace PDF2Img  {      public partial class Form1 : Form      {          public Form1()          {              InitializeComponent();          }          private void button1_Click(object sender, EventArgs e)          {              PDFConvert convertor = new PDFConvert();              convertor.pdf2jpgTest();              Image img = Image.FromFile(@"C://tmp//pdfimg//out.jpg");              myBitmap = new Bitmap(img);              Graphics G = this.CreateGraphics();              GraphicsUnit GU = G.PageUnit;              BMPContainer = myBitmap.GetBounds(ref GU); //X,Y = 0             // Graphics g = this.CreateGraphics();              //g.DrawImage(myBitmap, 1, 1);              this.Invalidate();          }          private Bitmap myBitmap;          private RectangleF BMPContainer;          protected override void OnPaint(PaintEventArgs e)          {              Graphics G = e.Graphics;              if (myBitmap != null)              {                             G.DrawImage(myBitmap,

首先准备一张位图图像source.bmp,将它保存在bmp.aspx同一目录中 复制代码 代码如下:        <%@ Page language="c#" %>     <%@ Import Namespace="System.Drawing" %>     <%@ Import Namespace="System.Drawing.Imaging" %>         <script language="c#" runat="server">     private void Page_Load(object sender, System.EventArgs e)     {     // 设置 mime 类型为image/jpeg,即将向浏览器输出JPGE格式的图像     Response.Clear();     Response.ContentType="image/jpeg";         Bitmap OutputBitmap = new Bitmap(Server.MapPath("source.bmp"));//新建BitMap对象     System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();     long[] quality = new long[1];     int comp = 0;     if (Request.QueryString["comp"] != "") { comp = Convert.ToInt16(Request.QueryString["comp"]); }     quality[0] = comp; //0 to 100 最高质量为100     System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);     encoderParams.Param[0] = encoderParam;     ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();//获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。     ImageCodecInfo jpegICI = null;     for (int x = 0; x < arrayICI.Length; x++)     {     if (arrayICI[x].FormatDescription.Equals("JPEG"))     {     jpegICI = arrayICI[x];//设置JPEG编码     break;     }     }     if (jpegICI != null)     {     OutputBitmap.Save(Response.OutputStream, jpegICI, encoderParams);//将位图对象以流格式并用JPEG编解码参数保存到输出流。     }     // clean up     OutputBitmap.Dispose();     }     </script>     在浏览器地址输入:http://localhost/bmp.aspx?comp=0     将会看到图像,调整comp的值,

1.引言 2.实现代码 2.1.服务器端代码 2.1.1. 文件上传状态类(FileUploadStatus) 2.1.2. 文件上传状态侦听类(FileUploadListener) 2.1.3. 后台服务类(BackGroundService) 2.1.4. 文件上传状态控制类(BeanControler) 2.2. 客户端代码 2.2.1. AjaxWrapper.js 2.2.2. fileUpload.html 2.2.3. result.jsp 2.2.4. fileUpload.css 2.3. 配置文件 3. 结语 <!--google_ad_client = "pub-1832179689702023";google_ad_width = 336;google_ad_height = 280;google_ad_format = "336x280_as";google_ad_type = "text_image";//2007-01-10: 336_280google_ad_channel = "7111701428";google_color_border = "FFFFFF";google_color_bg = "FFFFFF";google_color_link = "0000FF";google_color_text = "000000";google_color_url = "3D81EE";//--> BODY { MARGIN: 15px; FONT: 13px Georgia, "Lucida Grande", Arial, sans-serif; COLOR: #000; LETTER-SPACING: 0.01em; BACKGROUND-COLOR: white}  1. 引言   基于浏览器的文件上传,特别是对于通过<input type="file">标签来实现上传的情况, 存在着严重的性能问题,因为用户提交了文件之后,在浏览器把文件上传到服务器的过程中,界面看上去似乎是静止的,如果是小文件还好些,如果不幸需要上传的是几兆、几十兆甚至上百兆的文件,我相信那是一种非常痛苦的体验,我们中间的很多人应该都有过此种不堪的经历。(一笑)  现在我就针对这个问题给出一个解决方案,我们将实现一个具有监控能力的WEB上传的程序——它不仅把文件上传到服务器,而且"实时地"监视文件上传的实际过程。解决方案的基本思路是这样的:   在Form提交上传文件同时,使用AJAX周期性地从Servlet轮询上传状态信息   然后,根据此信息更新进度条和相关文字,及时反映文件传输状态   如果用户取消上传操作,则进行相应的现场清理工作:删除已经上传的文件,在Form提交页面中显示相关信息   如果上传完毕,显示已经上传的文件内容(或链接) 在介绍源代码之前,我们先来看看程序运行界面:  2. 实现代码   实现代码想当然的有服务器端代码和客户端代码(呵呵),我们先从服务器端开始。 2.1. 服务器端代码  2.1.1. 文件上传状态类(FileUploadStatus)   使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介,通过对这个类对象提供上传状态作为服务器回应发送给web客户端, web客户端使用JavaScript获得文件上传状态。源代码如下:/** * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail:[email protected] */package liuzuochen.sample.upload;import java.util.*;public class FileUploadStatus { //上传用户地址 private String uploadAddr; //上传总量 private long uploadTotalSize = 0; //读取上传总量 private long readTotalSize = 0; //当前上传文件号 private int currentUploadFileNum = 0; //成功读取上传文件数 private int successUploadFileCount = 0; //状态 private String status = ""; //处理起始时间 private long processStartTime = 0l; //处理终止时间 private long processEndTime = 0l; //处理执行时间 private long processRunningTime = 0l; //上传文件URL列表 private List uploadFileUrlList = new ArrayList(); //取消上传 private boolean cancel = false; //上传base目录 private String baseDir = ""; public FileUploadStatus() { } public String getBaseDir() { return baseDir; } public void setBaseDir(String baseDir) { this.baseDir = baseDir; } public boolean getCancel() { return cancel; } public void setCancel(boolean cancel) { this.cancel = cancel; } public List getUploadFileUrlList() { return uploadFileUrlList; } public void setUploadFileUrlList(List uploadFileUrlList) { this.uploadFileUrlList = uploadFileUrlList; } public long getProcessRunningTime() { return processRunningTime; } public void setProcessRunningTime(long processRunningTime) { this.processRunningTime = processRunningTime; } public long getProcessEndTime() { return processEndTime; } public void setProcessEndTime(long processEndTime) { this.processEndTime = processEndTime; } public long getProcessStartTime() { return processStartTime; } public void setProcessStartTime(long processStartTime) { this.processStartTime = processStartTime; } public long getReadTotalSize() { return readTotalSize; } public void setReadTotalSize(long readTotalSize) { this.readTotalSize = readTotalSize; } public int getSuccessUploadFileCount() { return successUploadFileCount; } public void setSuccessUploadFileCount(int successUploadFileCount) { this.successUploadFileCount = successUploadFileCount; } public int getCurrentUploadFileNum() { return currentUploadFileNum; } public void setCurrentUploadFileNum(int currentUploadFileNum) { this.currentUploadFileNum = currentUploadFileNum; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public long getUploadTotalSize() { return uploadTotalSize; } public String getUploadAddr() { return uploadAddr; } public void setUploadTotalSize(long uploadTotalSize) { this.uploadTotalSize = uploadTotalSize; } public void setUploadAddr(String uploadAddr) { this.uploadAddr = uploadAddr; } public String toJSon() { StringBuffer strJSon = new StringBuffer(); strJSon.append("{UploadTotalSize:").append(getUploadTotalSize()).append( ",") .append("ReadTotalSize:").append(getReadTotalSize()).append(",") .append("CurrentUploadFileNum:").append(getCurrentUploadFileNum()). append(",") .append("SuccessUploadFileCount:").append( getSuccessUploadFileCount()).append(",") .append("Status:'").append(getStatus()).append("',") .append("ProcessStartTime:").append(getProcessStartTime()). append(",") .append("ProcessEndTime:").append(getProcessEndTime()).append( ",") .append("ProcessRunningTime:").append(getProcessRunningTime()). append(",") .append("Cancel:").append(getCancel()).append("}"); return strJSon.toString(); }}  2.1.2. 文件上传状态侦听类(FileUploadListener)   使用Common-FileUpload 1.2版本(20070103)。此版本提供了能够监视文件上传情况的ProcessListener接口,使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。 FileUploadListener类实现了ProcessListener,在整个文件上传过程中,它对上传进度进行监控,并且根据上传 情况实时的更新上传状态Bean。源代码如下:/** * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail:[email protected] */package liuzuochen.sample.upload;import org.apache.commons.fileupload.ProgressListener;import javax.servlet.http.HttpServletRequest;public class FileUploadListener implements ProgressListener{ private HttpServletRequest request=null; public FileUploadListener(HttpServletRequest request){ this.request=request; } /** * 更新状态 */ public void update(long pBytesRead, long pContentLength, int pItems){ FileUploadStatus statusBean= BackGroundService.getStatusBean(request); statusBean.setUploadTotalSize(pContentLength); //读取完成 if (pContentLength == -1) { statusBean.setStatus("完成对" + pItems +"个文件的读取:读取了 " + pBytesRead + " bytes."); statusBean.setReadTotalSize(pBytesRead); statusBean.setSuccessUploadFileCount(pItems); statusBean.setProcessEndTime(System.currentTimeMillis()); statusBean.setProcessRunningTime(statusBean.getProcessEndTime()); //读取中 } else { statusBean.setStatus("当前正在处理第" + pItems +"个文件:已经读取了 " + pBytesRead + "/" + pContentLength+ " bytes."); statusBean.setReadTotalSize(pBytesRead); statusBean.setCurrentUploadFileNum(pItems); statusBean.setProcessRunningTime(System.currentTimeMillis()); } BackGroundService.saveStatusBean(request,statusBean); }}当前1/2页 12下一页阅读全文您可能感兴趣的文章:基于jsp的AJAX多文件上传的实例servlet+JSP+mysql实现文件上传的方法利用jsp+Extjs实现动态显示文件上传进度jsp中点击图片弹出文件上传界面及预览功能的实现jsp文件上传与下载实例代码Jsp页面实现文件上传下载类代码JSP使用Common FileUpload组件实现文件上传及限制上传类型实例代码Tags:AJAX和JSP实现的基于WEB的文件上传的进度控制代码 相关文章2013-05-05AJAX和三层架构实现分页功能具体思路及代码2017-03-03Ajax校验是否重复的实现代码2015-11-11jQuery Ajax 实例详解 ($.ajax、$.post、$.get)2016-06-06ajax内部值外部调用不了的原因及解决方法2007-03-03ajax中指定innerHTML时如何应用其中的SCRIPT的研究2015-12-12AJax与Jsonp跨域访问问题小结2017-08-08利用 FormData 对象和 Spring MVC 配合实现Ajax文件下载功能2016-06-06AjaxToolKit之Rating控件的使用方法2014-01-01ajax给全局变量赋值问题解决示例2007-01-01配合AJAX天气预报的webService 之asp最新评论 大家感兴趣的内容1jquery ajax 向后台传递数组参数2ajax readyState的五种状态详解3ajax传递多个参数具体实现4jQuery ajax中使用serialize()方5ajax中的async属性值之同步和异步6AJAX 缓存问题的两种解决方法(IE7ajax 技术和原理分析8自己动手打造ajax图片上传(网上没9Ajax请求中的异步与同步,需要注10jQuery实现AJAX定时刷新局部页面最近更新的内容甩掉ashx和asmx使用jQuery.ajaxWebServicAJAX和WebService实现邮箱验证(无刷新验证MVC中基于Ajax和HTML5实现文件上传功能prototype试用整理资料Ajax 提交表单数据到入库的全盘操作流程分ajax与传统web开发的异同点浅析Ajax后台success传来json数据的问题反向Ajax 30分钟快速掌握Ajax四种元素的关系介绍ajax异步处理POST表单中的数据示例代码 常用在线小工具 关于我们 - 广告合作 - 联系我们 - 免责声明 - 网站地图 - 投诉建议 - 在线投稿©CopyRight 2006-2017 JB51.Net Inc All Rights Reserved. 脚本之家 版权所有(function(){ var bp = document.createElement('script'); bp.src = '//push.zhanzhang.baidu.com/push.js'; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s);})();if (top.location != self.location)top.location=self.location;$(function(){ $('#content').find('img').each(function(){ var img = this; if (img.width >= 650){ img.style.width = "650px"; img.style.height = "auto"; //$(img).removeAttr('height'); var aTag = document.createElement('a'); aTag.href = img.src; aTag.target="_blank"; $(aTag).addClass('bPic') .insertAfter(img).append(img) } }); $(window).scroll(function() { //rFixedBox跟随滚动 var h = $(window).height(); var top = $(window).scrollTop(); var rFixedBox = $('.rFixedBox').prev().offset(); var fixedTop = rFixedBox.top; if(top>=fixedTop+344) { var h1 = parseInt($('#content').children('.main').height()); if(parseInt(top) + 340 < h1){ $('.rFixedBox').css({'position':'fixed','top': 0}); }else{ $('.rFixedBox').css({'position':'absolute','top': h1-510}); } } else { $('.rFixedBox').css({'position':'static', 'top':0}); } /* return true;*/ });/*$(document).ready(function() { $("#content img").unveil();}); */SyntaxHighlighter.autoloader( 'applescript /jslib/syntaxhighlighter/scripts/shBrushAppleScript.js', 'actionscript3 as3 /jslib/syntaxhighlighter/scripts/shBrushAS3.js', 'bash shell /jslib/syntaxhighlighter/scripts/shBrushBash.js', 'coldfusion cf /jslib/syntaxhighlighter/scripts/shBrushColdFusion.js', 'cpp c /jslib/syntaxhighlighter/scripts/shBrushCpp.js', 'obj-c objc /jslib/syntaxhighlighter/scripts/shBrushObjC.js', 'c# c-sharp csharp /jslib/syntaxhighlighter/scripts/shBrushCSharp.js', 'css /jslib/syntaxhighlighter/scripts/shBrushCss.js', 'delphi pascal /jslib/syntaxhighlighter/scripts/shBrushDelphi.js', 'diff patch pas /jslib/syntaxhighlighter/scripts/shBrushDiff.js', 'erl erlang /jslib/syntaxhighlighter/scripts/shBrushErlang.js', 'groovy /jslib/syntaxhighlighter/scripts/shBrushGroovy.js', 'haxe hx /jslib/syntaxhighlighter/scripts/shBrushHaxe.js', 'java /jslib/syntaxhighlighter/scripts/shBrushJava.js', 'jfx javafx /jslib/syntaxhighlighter/scripts/shBrushJavaFX.js', 'js jscript javascript /jslib/syntaxhighlighter/scripts/shBrushJScript.js', 'perl pl /jslib/syntaxhighlighter/scripts/shBrushPerl.js', 'php /jslib/syntaxhighlighter/scripts/shBrushPhp.js', 'text plain /jslib/syntaxhighlighter/scripts/shBrushPlain.js', 'py python /jslib/syntaxhighlighter/scripts/shBrushPython.js', 'ruby rails ror rb /jslib/syntaxhighlighter/scripts/shBrushRuby.js', 'scala /jslib/syntaxhighlighter/scripts/shBrushScala.js', 'sql /jslib/syntaxhighlighter/scripts/shBrushSql.js', 'vb vbnet /jslib/syntaxhighlighter/scripts/shBrushVb.js', 'ps powershell /jslib/syntaxhighlighter/scripts/shBrushPowerShell.js', 'xml xhtml xslt html /jslib/syntaxhighlighter/scripts/shBrushXml.js');SyntaxHighlighter.all();});var ourl="";jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);jbLoader();jbLoader(true);//tu+var cpro_id = "u1893014";document.write('<scri'+'pt src="http://cpro.baidustatic.com/cpro/ui/i.js" type="text/javascript"></s'+'cript>');window.changyan.api.config({appid: 'cyrHH3dwi',conf:

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 5060网址大全 网站地图

联系我们

827570882

扫描二维码分享到微信