• 我的工作問題集(VS2005)<續>


    21.如何將組織好的string變量匯出成Excel文檔?
    CS Code:
    protected void ToExcel()
    {
         string sStr="";
         /*省略組織sStr的代碼*/
         ...

         Response.Clear();
        Response.AppendHeader("Content-Disposition", "attachment;filename=TEST" + DateTime.Now.Date.ToString("yyyyMMdd") + ".xls");
        Response.ContentType = "application/vnd.ms-excel";
        Response.ContentEncoding = Encoding.Default;
        Response.Write(sStr);
        Response.Flush();
        Response.Close();
    }

    22.我正在學習中的Delegate(轉載)
    CS Code:
    Delegate
    delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类。与其它的类不同,delegate类能够拥有一个签名(signature),并且它只能持有与它的签名相匹配的方法的引用。它所实现的功能与C/C++中的函数指针十分相似。它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。
    实现一个delegate是很简单的,通过以下3个步骤即可实现一个delegate:
    1.声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。
    2. 创建delegate对象,并将你想要传递的函数作为参数传入。
    3. 在要实现异步调用的地方,通过上一步创建的对象来调用方法。
    using System;

    public class MyDelegateTest
    {
            // 步骤1,声明delegate对象
            public delegate void MyDelegate(string name);

            // 这是我们欲传递的方法,它与MyDelegate具有相同的参数和返回值类型
            public static void MyDelegateFunc(string name)
            {
                      Console.WriteLine("Hello, ", name);
            }
            public static void Main()
            {
                      // 步骤2,创建delegate对象
     MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc);
                     // 步骤3,调用delegate
                     md("sam1111");
            }
    }

    输出结果是:Hello, sam1111

    了解了delegate,下面我们来看看,在C#中对事件是如何处理的。

    C#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:

    public delegate void MyEventHandler(object sender, MyEventArgs e);

    其中的两个参数,sender代表事件发送者,e是事件参数类。MyEventArgs类用来包含与事件相关的数据,所有的事件参数类都必须从System.EventArgs类派生。当然,如果你的事件不含参数,那么可以直接用System.EventArgs类作为参数。

    就是这么简单,结合delegate的实现,我们可以将自定义事件的实现归结为以下几步:

    1.定义delegate对象类型,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。
    2.定义事件参数类,此类应当从System.EventArgs类派生。如果事件不带参数,这一步可以省略。
    3.定义事件处理方法,它应当与delegate对象具有相同的参数和返回值类型。
    4. 用event关键字定义事件对象,它同时也是一个delegate对象。
    5.用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。
    6.在需要触发事件的地方用调用delegate的方式写事件触发方法。一般来说,此方法应为protected访问限制,既不能以public方式调用,但可以被子类继承。名字是OnEventName。
    7. 在适当的地方调用事件触发方法触发事件。

    下面是一个简单的例子:

    using System;
    public class EventTest
    {
            // 步骤1,定义delegate对象
           public delegate void MyEventHandler(object sender, System.EventArgs e);
           // 步骤2省略
           public class MyEventCls
           {
                    // 步骤3,定义事件处理方法,它与delegate对象具有相同的参数和返回值类// 型
                    public  void MyEventFunc(object sender, System.EventArgs e)
                    {
                               Console.WriteLine("My event is ok!");
                    }
           }
           // 步骤4,用event关键字定义事件对象
          private event MyEventHandler myevent;
          private MyEventCls myecls;
          public EventTest()
          {
                    myecls = new MyEventCls();
              :      // 步骤5,用+=操作符将事件添加到队列中
                    this.myevent += new MyEventHandler(myecls.MyEventFunc);
          }
          // 步骤6,以调用delegate的方式写事件触发函数
         protected void OnMyEvent(System.EventArgs e)
          {
                   if(myevent != null)
                           myevent(this, e);
          }
         public void RaiseEvent()
          {
                   EventArgs e = new EventArgs();
          :         // 步骤7,触发事件
                   OnMyEvent(e);
          }
          public static void Main()
          {
                   EventTest et = new EventTest();
                   Console.Write("Please input ''a'':");
                   string s = Console.ReadLine();
                   if(s == "a")
                   {
                         et.RaiseEvent();
                   }
                   else
                  {
                            Console.WriteLine("Error");
                  }
          }
    }

    输出结果如下,红色为用户的输入:

    Please input ‘a’: a
    My event is ok!

    23.存储过程学习(转载)
    存储过程 包含三部分: 声明,执行部分,异常。
    可以有无参数程序和带参数存储过程。
    无参程序语法

    1 create or replace procedure NoParPro
    2 as  ;
    3 begin
    4 ;
    5 exception
    6     ;
    7 end;
    8 


       带参存储过程实例

     1 create or replace procedure queryempname(sfindno emp.empno%type) as
     2        sName emp.ename%type;
     3        sjob emp.job%type;
     4 begin
     5        ....
     7 exception
              ....
    14 end;
    15 


       带参数存储过程含赋值方式

     1 create or replace procedure runbyparmeters  (isal in emp.sal%type,
                                sname out 
    varchar,sjob in out varchar)
     2  as icount number;
     3  begin
     4       select count(*into icount from emp where sal>isal and job=sjob;
     5       if icount=1 then
     6         ....
     9       else
    10         ....
    12       end if;
    13  exception
    14       when too_many_rows then
    15       DBMS_OUTPUT.PUT_LINE('返回值多于1行');
    16       when others then
    17       DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS过程中出错!');
    18  end;
    19 


      过程调用
     
    方式一

     1 declare
     2        realsal emp.sal%type;
     3        realname varchar(40);
     4        realjob varchar(40);
     5  begin
     6        realsal:=1100;
     7        realname:='';
     8        realjob:='CLERK';
     9        runbyparmeters(realsal,realname,realjob);     --必须按顺序
    10        DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB);
    11  END;
    12 


      方式二

     1 declare
     2       realsal emp.sal%type;
     3       realname varchar(40);
     4       realjob varchar(40);
     5 begin
     6       realsal:=1100;
     7       realname:='';
     8       realjob:='CLERK';
     9       runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob);  --指定值对应变量顺序可变
    10       DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB);
    11 END;
    12 

    24.泛型的FindAll()方法
    我在工作中遇到要像DataSet一样过滤数据集中的数据,但是数据返回类型是泛型,因此要用List.FindAll()方法.
    CS Code:
    //List<Model> listModel已经有值,listModelNew为过滤后所要的数据集
    List<Model> listModelNew=listModel.FindAll(delegate(Model m)
    {
        return m.UserId==9527;
    });


    25.如何將DataSet中的數據導出為Excel?
    CS Code:
       Response.Clear();
       Response.Charset = "big5";//繁體
       Response.ContentType = "application/vnd.ms-excel";
       System.IO.StringWriter oSW = new System.IO.StringWriter();
       HtmlTextWriter oHW = new HtmlTextWriter(oSW);
       DataGrid oDG = new DataGrid();
       oDG.DataSource = oDS.Tables[0];
       oDG.DataBind();
       oDG.RenderControl(oHW);
       Response.Write(oSW.ToString());
       Response.Flush();
       Response.Close();


    26.如何画柏拉图?
    CS Code:
    public void Render(string title, string subTitle, int width, int height,
                string XDesc, string YLeftDesc, string YRightDesc,
                DataTable DT, Stream target)
            {
                int CHART_TOP = 80;     //圖距頂段
                int CHART_HEIGHT = height - 180; //圖高
                int CHART_LEFT = 70;     //圖距左邊
                int CHART_WIDTH = width - 140;  //圖寬

                //計算最高點
                int highPoint = 0;
                foreach (DataRow dr in DT.Rows)
                {
                    highPoint += int.Parse(dr[0].ToString());
                }
                //建立一個Graphics對象實例
                Bitmap bm = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(bm);

                //設置條型圖形和文字屬性
                g.SmoothingMode = SmoothingMode.Default;
                g.TextRenderingHint = TextRenderingHint.AntiAlias;

                //設定畫布和邊框
                g.Clear(Color.LightSkyBlue);
                g.FillRectangle(Brushes.LightYellow, CHART_LEFT - 1, CHART_TOP, CHART_WIDTH + 2, CHART_HEIGHT + 2);
                //添主圖背景為淡黃色

                //畫座標*********************************************
                float sCale = float.Parse(highPoint.ToString()) / 4;
                float tempPoint = 0;
                for (int i = CHART_TOP + CHART_HEIGHT; i >= CHART_TOP; i -= CHART_HEIGHT / 4)
                {
                    g.DrawLine(Pens.Black, new Point(CHART_LEFT, i), new Point(CHART_LEFT + CHART_WIDTH, i));
                    g.DrawString(tempPoint.ToString(), new Font("Arial", 9, FontStyle.Regular), Brushes.Black, new Point(CHART_LEFT - 25, i - 6));
                    tempPoint += sCale;
                }//畫橫線和左邊刻度

                g.DrawLine(Pens.Black, new Point(CHART_LEFT, CHART_TOP), new Point(CHART_LEFT, CHART_TOP + CHART_HEIGHT));
                //左座標
                g.DrawString(YLeftDesc, new Font("Arial", 9, FontStyle.Regular), Brushes.Black, new Point(CHART_LEFT - 65, CHART_TOP + CHART_HEIGHT / 2));
                //左座標描述
                g.DrawLine(Pens.Black, new Point(CHART_LEFT + CHART_WIDTH, CHART_TOP), new Point(CHART_LEFT + CHART_WIDTH, CHART_TOP + CHART_HEIGHT));
                //右座標
                g.DrawString(YRightDesc, new Font("Arial", 9, FontStyle.Regular), Brushes.Black, new Point(CHART_LEFT + CHART_WIDTH + 35, CHART_TOP + CHART_HEIGHT / 2));
                //右座標描述
                g.DrawString(XDesc, new Font("Arial", 9, FontStyle.Regular), Brushes.Black, new Point(CHART_LEFT + CHART_WIDTH / 2 - 40, CHART_TOP + CHART_HEIGHT + 30));
                //底座標描述

                int sCaleR = CHART_HEIGHT / 10;
                tempPoint = CHART_TOP;
                for (int i = 10; i >= 0; i--)
                {
                    g.DrawLine(Pens.Black, new Point(CHART_LEFT + CHART_WIDTH, int.Parse(tempPoint.ToString())), new PointF(float.Parse((CHART_LEFT + CHART_WIDTH + 5).ToString()), tempPoint));
                    g.DrawString((i * 10).ToString(), new Font("Arial", 9, FontStyle.Regular), Brushes.Black, new PointF(float.Parse((CHART_LEFT + CHART_WIDTH + 12).ToString()), tempPoint - 5));
                    tempPoint += sCaleR;
                }//右座標刻度

                //畫大標題
                g.DrawString(title, new Font("Arial", 14), Brushes.Black, new PointF(width / 2 - 150, 15));
                //畫小標題
                g.DrawString(subTitle, new Font("Arial", 12), Brushes.Black, new PointF(width / 2 - 40, 45));


                //畫條型圖
                float barWidth = CHART_WIDTH / (DT.Rows.Count * 2);
                PointF barOrigin = new PointF(CHART_LEFT + (barWidth / 2), 0);
                float barHeight = 0;
                PointF[] linePoints = new PointF[DT.Rows.Count];       //描點個數陣列

                float Percents = 0;
                for (int i = 0; i < DT.Rows.Count; i++)
                {
                    barHeight = Convert.ToSingle(DT.Rows[i][0]) * CHART_HEIGHT / highPoint;
                    barOrigin.Y = CHART_TOP + CHART_HEIGHT - barHeight;
                    g.FillRectangle(new SolidBrush(ChartUtil.GetChartItemColor(i)), barOrigin.X, barOrigin.Y, barWidth, barHeight);
                    //畫矩形
                    g.DrawString(Convert.ToString(DT.Rows[i][1]), new Font("Arial", 8, FontStyle.Regular), Brushes.Black, new PointF(barOrigin.X, CHART_TOP + CHART_HEIGHT + 5), new StringFormat(StringFormatFlags.DirectionVertical));
                    //畫條形描述
                    Percents += Convert.ToSingle(DT.Rows[i][0]) / highPoint;
                    g.DrawString(Percents.ToString("0.00%"), new Font("Arial", 8, FontStyle.Regular), Brushes.Black, new PointF(barOrigin.X - 5, CHART_TOP + (1 - Percents) * CHART_HEIGHT - 15));
                    //畫白份比
                    linePoints[i] = new PointF(barOrigin.X + barWidth / 2, CHART_TOP + (1 - Percents) * CHART_HEIGHT);
                    //畫連線點
                    barOrigin.X = barOrigin.X + (barWidth * 2);
                }
                g.DrawLines(Pens.Red, linePoints);//連線

                //輸出圖像
                bm.Save(target, ImageFormat.Gif);

                //回收資源
                bm.Dispose();
                g.Dispose();
            }

    27.HAVING的使用
    把 HAVING 加入 SQL 的原因是,WHERE 无法应用于合计函数,而如果没有 HAVING,就无法测试结果条件。
    example:
    表 "Sales":

    Company Amount
    W3Schools 5500
    IBM 4500
    W3Schools 7100
    SQL:
    SELECT Company,SUM(Amount) FROM Sales
    GROUP BY Company
    HAVING SUM(Amount)>10000

    结果:

    Company SUM(Amount)
    W3Schools 12600

    28.C#操作文件(转载)

    C# 操作文件

    在.NET Framework中进行的所有的输入和输出工作都要使用到流。流是串行化设备的抽象串行化设备可以以线性方式存储数据,并可以以同样的方式访问:一次访问—个字节。此设备可以是磁盘文件、打印机、内存位置和或任何其他支持以线性方式读写的对象。
    当向某些外部目标写数据时,就要用到输出流,这可以是物理磁盘文件、网络位置、打印机或其他程序。 

    常用的类:

    File------实用类,提供许多静态方法,用于移动、删除、和复制文件。

    Directory------实用类,提供许多静态方法,用于移动、删除和复制目录。

    Path------ 实用类,用于处理路径名称。

    FileInfo------表示磁盘上的物理文件,具有可以处理此文件的方法,要完成对文件的读写工作,就必须创建Stream对像。

    DirectoryInfo------表示磁盘上的物理目录,具有可以处理此目录的方法

    FileStream-------表示可以被写或被读,或二者都可的文件,此文件可以同步或异步读和写

    StreamReader------从流中读取字符数据,并可通过使用FileStream被创建为基类。

    StreamWriter------向流写字符数据,可通过使用FileStream被创建为基类。

    FileSystemWatcher---- FileSystemWatcher是用于监控文件和目录,并在这些位置发生变化时,给出应用程序可以捕获的事件。

    FileDirectory

    作为实用类,File和Directory类都提供了许多方法,用于处理文件系统以及其中的文件和目录。这些是静态方法,涉及移动文件、查询和更新属性并创建FileStream对象。

    File一些最常用的静态方法:

    Copy()------将文件复制到规定的位置

    Create()------在规定的位置上创建文件

    Delete()------删除文件

    Open()-------在规定的路径上返回FileStream对像

    Move()------将规定的文件移动到新位置,可以在新位置给文件规定不同的名字

    Directory的一些常用的静态方法

    CreateDirectory()------创建具有规定路径的目录

    Delete()------删除规定的目录以及其中的所有文件

    GetDirectories()------返回表示当前目录之下的目录的Directory对像的数组

    GetFiles()-------返回在当前目录中的File对像的数组

    Move()------将规定的目录移动到新位置。可以在新位置为文件夹规定一个新名称

    FileInfo 类

    FileInfo类不像File类,它没有静态方法,仅可用于实例化的对像。FileInfo对像表示在磁盘或网络位置的文件,注意它不是流,为了读写文件,必须创建Stream对像。

    fileInfo提供了下面的关于基础性的文件的属性,这些属性可能用来更新文件。

    Attributes-----获取或设置当前文件的属性

    CreationTime------获取当前文件的创建日期和时间

    DirectoryName------获取文件目录的路径

    Exists------判断是否存在文件

    FullName------检索文件的完整路径

    Length------获取文件的容量

    Name------仅仅返回文件的名称,而不是完整的文件位置路径、

        当在.NET代码中规定路径名时,您可以使用绝对路径名,也可以使用相对路行名。绝对路径名显式地规定文件或目录来自于哪—个己知的位置——比如是c:驱动器。它的—个范例是C:\work\LogFile.txt。注意它淮确地定义了其位置。

      相对路径名相对于应用程序在文件系统上运行的位置。通过使用相对路径名称,无需规定已知的驱动器或位置;当前的目录就是起点。例如,如果应用程序运行在c:\DeVelopment\FileDemo目录上(这里的应用程序是指代码生成后的exe文件),并使用了相对路径“LogFile.txt,”,则该文件就位于C:\DeVelopment\FileDemo\LogFile.txt中。为了上移目录,则使用.. 字符。这样,在同一个应用程中路径“../test.txt”是指向应用程序所在的目录的上一级目录里的文件test.txt。

    FileStream对象

    FileStream对象表示在磁盘或网络路径上指向文件的流。当类提供向文件读写字节的方法时,经常使用StreamReader或StreamWriter执行这些功能。这是因为FileStream类操作字节和字节数组,而Stream类操作字符数据。字符数据易于使用,但是有些操作比如随机文件访问,就必须由FileStream对象执行。

    FileStream对象的构造函数:

    FileStream aFile = new FileStream(“Log.txt”,FileMode.OpenOrCreate);

     FileMode枚举具有几种成员:

    Append------如果文件存在,就打开文件,将文件位置移动到文件的末尾,并创建一个新文件。FileMode.Append仅可以与枚举FileAccess.Write联合使用

    Create------创建新文件;如果存在这样的文件,就破坏它。

    CreateNew------创建新文件,但是如果已经存在此文件,则抛出异常

    Open------打开现有的文件,但是不存在所指定的文件,则抛出异常

    OpenOrCreate------如果文件存在,则规定打开文件,否则就创建新文件,如果文件已经存在,则保留在文件中的数据

    Truncate------打开现有文件,清除其内容,然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期,必须存在有文件,否则就抛出异常

    访问级别

     前面的构造函数默认以只读模式打开文件,需要一个附加参数规定不同的访问级别,此参数是FileAccess参数

    FileStream aFile=new FileStream(”Log.txt”,fileMode.OpenOrCreate,FileAccess.Write)

         FileAccess枚举有三种类型:Read、Write、ReadWrite.此属性的作用是:基于用户的身份验证级别改变用户对文件的访问

     读取文件的位置用seek:public long Seek(long offset,SeekOrigin origin)

     Long offset是规定文件指针以字节为单位的移动距离;SeekOrigin origin是规定开始计算的起始位置,此枚举包含3个值:Begin,Current和End。

       例:aFile.Seek(8,SeekOrigin.Begin);// SeekOrigin.Begin指得是文件指针从文件的第一个字节起;而参数‘8‘指得是移动到文件的第8个字节

       例2:afile.Seek(2,SeekOrigin.Current)//在当前位置开始,再移动2个字节。

       例3:aFile.Seek(-5,SeekOrigin.End)//在文件末端位置开始,倒数5个字节。

      读取数据

    使用FileStream类读取数据不像使用StreamReader和StreamWriter类读取数据那么容易,这是因为FileStream类只能处理原始字节(raw byey),这使得FileStream类可以用于任何数据文件,而不仅仅是文本文件,通过读取字节数据就可以读取类似图像和声音的文件。这种灵活性的代价是不能使用它直接读入字符串,而使用StreamWriter和StreaMeader类却可以这样处理,从是有几种转换类可以很容易地将字节数组转换为字符数组,或者进行相反的操作。

    Read()方法是从FileStream对象所指向的文件访问数据的主要手段:

    Public int Read(byte[] array,int offset, int count)//第一个参数是被传输进来的字节数组,用以接受FileStream对象中的数据。第二个参数是字节数组中开始写入数据的位置,它通常是0,表示从数组的开端的文件中向数组写数据,最后一个参数是规定从文件中读出多少字节。

    写入数据

    写入数据的流程是先获取字节数组,再把字节数据转换为字符数组,然后把这个字符数组用Write()方法写入到文件中,当然在写入的过程中,可以确定在文件的什么位置写入,写多少字符等等。

    文件读写的范例:

    读取文件
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace myFile
    {
        
    class Program
        
    {
            
    static void Main(string[] args)
            
    {
                
    byte[] byData = new byte[100];//建立一个FileStream要用的字节组
                char[] charData = new char[100];//建立一个字符组

                
    try
                
    {
                    FileStream aFile 
    = new FileStream("http://www.cnblogs.com/http://www.cnblogs.com/Data.txt", FileMode.Open);//实例化一个FileStream对象,用来操作data.txt文件,操作类型是
                    
                    aFile.Seek(
    55, SeekOrigin.Begin);//把文件指针指向,从文件开始位置向前55位字节所指的字节
                    aFile.Read(byData, 0100);//读取FileStream对象所指的文件到字节数组里
                }

                
    catch (IOException e)
                
    {
                    Console.WriteLine(
    "close");
                    
    return;
                }

                Decoder d 
    = Encoding.UTF8.GetDecoder();//
                d.GetChars(byData, 0, byData.Length, charData, 0);//将编码字节数组转换为字符数组

                Console.WriteLine(charData);
                Console.ReadLine();
                
    return;
            }

        }

    }


    写入文件:


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace myFile
    {
        
    class Program
        
    {
            
    static void Main(string[] args)
            
    {
                
    byte[] byData = new byte[100];//建立一个FileStream要用的字节组
                char[] charData = new char[100];//建立一个字符组

                
    try
                
    {
                    FileStream aFile 
    = new FileStream("http://www.cnblogs.com/http://www.cnblogs.com/Data.txt", FileMode.Open);//实例化一个FileStream对象,用来操作data.txt文件,操作类型是
                   
                    charData 
    = "我是谁?111?".ToCharArray();//将字符串内的字符复制到字符组里
                    aFile.Seek(0, SeekOrigin.End);
                    Encoder el 
    = Encoding.UTF8.GetEncoder();//编码器
                    el.GetBytes(charData, 0, charData.Length, byData, 0true);

                    aFile.Write(byData, 
    0, byData.Length);
                }

                
    catch (IOException e)
                
    {
                    Console.WriteLine(
    "close");
                    
    return;
                }

               
            }

        }

    }


     

    StreamWriter对像

    用FileWriter来随机读取文件是个好主意,而用StreamWriter可以直接把字符串写入文件中,它处理重要的转换和向FileStream对像写入工作。创建StreamWriter有很多方法:

    FileStream aFile = new FileStream(“Log.txt”,FileMode.CreatcNew);

    StreamWriter sw = new StreamWriter(aFile);

    也可直接从文件中创建StreamWriter对象:

      StreamWriter sw = new StreamWriter(“Log.txt”,true);

        后面这个Boolean值规定是附加文件还是创建新文件,如果此值为false,则就创建一个新文件,或者截取现有文件并打开它。如果此值设置为true,则打开文件,保留原来的数据,如果找不到文件,则创建一个新文件。注意:当创建FileStream对象时,您无法得到选项的范围。除了使用Boolean值附加或创建新文件外,我们根本就无法像使用FileStream类时那样规定FileMode属性;而且,您也无法设置FileAccess属性.因此您总是具有对文件的读写特权,为了使用任何高级参数,您必须在FileStream构造函数中规定这些参数,然后在FileStream对象中创建StreamWriter。


    例:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace StreamWriterFile
    {
        
    class Program
        
    {
            
    static void Main(string[] args)
            
    {
                
    try
                
    {
                    FileStream aFile 
    = new FileStream("data1.txt", FileMode.OpenOrCreate);//建立一个fileStream对象
                    StreamWriter sw = new StreamWriter(aFile);//用FileStream对像实例一个StreamWriter对象
                   
                    sw.Write(
    "first.");
                    sw.WriteLine(
    "hello world!!!");//写入字符串,方法WriteLine写入时后面跟一个换行符
                    sw.Write("This is a");//写入字符串,方法Write写入时没有换行符
                    sw.Write("string of characters.");
                    sw.Close();
    //用完后必须关闭对像
                }

                
    catch (IOException e)
                
    {
                    Console.WriteLine(e.ToString());
                }

            }

        }

    }


     

    StreamReader对象

     

     1.读取文件

    输入流用于从外部源读取数据,在很多情况下,数据源可以是磁盘上的文件或网络的某些位置,任何可能发送数据的位置都可以是数据源,比如网络应用程序,web服务,甚至是控制台。StreamReader是一个通用类,可以用于任何流;StreamReader对象的创建方式非常类似于StreamWriter对象的创建方式。

    StreamWriter类有两个基本的方法read和readLine

    Read()方法将流的下一个字符作为正整数值返回,如果到达了流的结尾处,则返回-1

    ReadLing()方法是读取并返回一行字符,如果返回为空,那么就是到达了流的结尾。

    ReadEnd()方法读小文件最好,它直接读取完整的文件并作为字符串返回。


    例:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace StreamReaderTest
    {
        
    class Program
        
    {
            
            
    static void Main(string[] args)
            
    {
                
    string strLine; 
                
    try
                
    {
                    Console.Write(
    "请输入文件路径及文件名:");
                    
    string mess = Console.ReadLine();
                    FileStream aFile 
    = new FileStream(mess, FileMode.Open);
                    StreamReader sr 
    = new StreamReader(aFile);//用FileStream对象实例化一个StreamReader对象
                    
    //strLine = sr.ReadToEnd();//读取完整的文件,如果用这个方法,就可以不用下面的while循环
                    strLine = sr.ReadLine();//  读取一行字符并返回
                    while (strLine != null)
                    
    {
                        Console.WriteLine(strLine);
                        strLine 
    = sr.ReadLine();
                    }

                    sr.Close();
                    Console.ReadLine();
                }

                
    catch (IOException e)
                
    {
                    Console.WriteLine(
    "an IOexception has been thrown!");
                    Console.WriteLine(e.ToString());
                    
    return;
                }

                
    return;
            }

        }

    }


     

    2.分隔文件

    读取使用逗号分隔的文件,string类提供了一种称为Split()的方法,可以用于将字符串按照提供的分隔符分隔成字符组.

    例:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace CommaValues
    {
        
    class Program
        
    {
            
    static void Main(string[] args)
            
    {
                
    while (true)
                
    {
                    
    string strLine;
                    
    string[] strArray;
                    
    char[] charArray = new Char[] ',' };
                    Console.Write(
    "请输入文件内容以逗号分隔的文件路径及文件名:");
                    
    string name = Console.ReadLine();

                    
    try
                    
    {
                        FileStream aFile 
    = new FileStream(name, FileMode.Open);
                        StreamReader sr 
    = new StreamReader(aFile);

                        strLine 
    = sr.ReadLine();
                        
    while (strLine != null)
                        
    {
                            strArray 
    = strLine.Split(charArray);
                            
    for (int x = 0; x <= strArray.GetUpperBound(0); x++)
                            
    {
                                Console.WriteLine(strArray[x].Trim());
                            }

                            strLine 
    = sr.ReadLine();
                        }

                        sr.Close();
                        
    //Console.ReadLine();
                    }

                    
    catch (IOException e)
                    
    {
                        Console.WriteLine(e.ToString());
                        
    return;
                    }

                    
    //return;
                }

            }

        }

    }


    29.在应用程序启动目录下创建XML文件

    protected void createXML(string xmlFileName)
    {

          try
          {
                    XmlTextWriter writer = new XmlTextWriter(".\\" + xmlFileName + ".xml", System.Text.Encoding.GetEncoding("utf-8"));
                    //使用自动缩进便于阅读  

                    writer.Formatting = Formatting.Indented;

                    writer.WriteRaw("<?xml version=" + "\"1.0" + "\" encoding=" + "\"utf-8" + "\" ?>");

                    //书写根元素  

                    writer.WriteStartElement("OnlineMonXML");

                    writer.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

                    writer.WriteAttributeString("version", "0.09.0005");

     

                    //添加次级元素  

                    writer.WriteStartElement("OnlineMonData");

     

                    //添加次级元素  

                    writer.WriteStartElement("Stations");

                    //添加次级元素  

                    writer.WriteStartElement("Station");

                    writer.WriteAttributeString("strStatuinType", "污染源自动监测");

                    writer.WriteAttributeString("strAreaID", "440100");

                    writer.WriteAttributeString("nStationID", "1");

     

                    //添加次级元素  

                    writer.WriteStartElement("Points");

                    //添加次级元素  

                    writer.WriteStartElement("Point");

                    writer.WriteAttributeString("strAreaID", "440100");

                    writer.WriteAttributeString("nStationID", "1");

                    writer.WriteAttributeString("nPointID", "1");

     

                    //添加次级元素  

                    writer.WriteStartElement("MonDatas");

                    //添加次级元素  

                    writer.WriteStartElement("MonData");

                    writer.WriteAttributeString("dMontime", "2004-03-02T00:50.0000000+08:00");

                    writer.WriteAttributeString("dDura", "POYOMODTOH5MOS");

     

                    //添加次级元素  

                    writer.WriteStartElement("ItemDatas");

     

                    //添加子元素  

                    writer.WriteStartElement("ItemData");

                    writer.WriteAttributeString("strItem", "COD");

                    writer.WriteAttributeString("fValue", "2.5");

                    writer.WriteAttributeString("strUnit", "mg/m3");

                    writer.WriteAttributeString("bChecked", "true");

                    //关闭次级元素DatabaseSetting  

                    writer.WriteEndElement();

     

                    writer.WriteStartElement("ItemData");

                    writer.WriteAttributeString("strItem", "水流量");

                    writer.WriteAttributeString("fValue", "30");

                    writer.WriteAttributeString("strUnit", "m3/s");

                    writer.WriteAttributeString("bChecked", "true");

     

                    //关闭次级元素DatabaseSetting  

                    writer.WriteEndElement();

                    //关闭根元素  

                    writer.WriteFullEndElement();

                    //将XML写入文件并关闭writer  

                    writer.Close();


           }
           catch (Exception ex)
           {
                Response.Write("<script language='javascript'>alert('"+ ex.Message +"')</script>");
           }
     }

    30.ASP.NET中防止用户多次登录的方法

    在web开发时,有的系统要求同一个用户在同一时间只能登录一次,也就是如果一个用户已经登录了,在退出之前如果再次登录的话需要报错。
      常见的处理方法是,在用户登录时,判断此用户是否已经在Application中存在,如果存在就报错,不存在的话就加到Application中(Application是所有Session共有的,整个web应用程序唯一的一个对象):

      string strUserId = txtUser.Text;
      ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
      if (list == null)
      {
      list = new ArrayList();
      }
      for (int i = 0; i < list.Count; i++)
      {
      if (strUserId == (list[i] as string))
      {
      //已经登录了,提示错误信息
      lblError.Text = "此用户已经登录";
      return;
      }
      }
      list.Add(strUserId);
      Application.Add("GLOBAL_USER_LIST", list);


      当然这里使用Cache等保存也可以。

      接下来就是要在用户退出的时候将此用户从Application中去除,我们可以在Global.asax的Session_End事件中处理:

      void Session_End(object sender, EventArgs e)
      {
      // 在会话结束时运行的代码。
      // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
      // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
      // 或 SQLServer,则不会引发该事件。
      string strUserId = Session["SESSION_USER"] as string;
      ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
      if (strUserId != null && list != null)


      {
      list.Remove(strUserId);
      Application.Add("GLOBAL_USER_LIST", list);
      }
      }


      这些都没有问题,有问题的就是当用户直接点浏览器右上角的关闭按钮时就有问题了。因为直接关闭的话,并不会立即触发Session过期事件,也就是关闭浏览器后再来登录就登不进去了。

      这里有两种处理方式:


      1、使用Javascript方式

      在每一个页面中加入一段javascript代码:

      function window.onbeforeunload()
      {
      if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey){
      window.open("logout.aspx");
      }
      }

      由于onbeforeunload方法在浏览器关闭、刷新、页面调转等情况下都会被执行,所以需要判断是点击了关闭按钮或是按下Alt+F4时才执行真正的关闭操作。


      然后在logout.aspx的Page_Load中写和Session_End相同的方法,同时在logout.aspx中加入事件:onload="javascript:window.close()"


      但是这样还是有问题,javascript在不同的浏览器中可能有不同的行为,还有就是当通过文件->关闭时没有判断到。

      2、使用xmlhttp方法(这种方法测试下来没有问题)

      在每个页面中加入如下的javascript(这些javascript也可以写在共通里,每个页面引入就可以了)

      var x=0;
      function myRefresh()
      {
      var httpRequest = new ActiveXObject("microsoft.xmlhttp");
      httpRequest.open("GET", "test.aspx", false);
      httpRequest.send(null);
      x++;
      if(x<60) //60次,也就是Session真正的过期时间是30分钟
      {
      setTimeout("myRefresh()",30*1000); //30秒
      }
      }
      myRefresh();

      在web.config中设置

    <sessionState mode="InProc" timeout="1"></sessionState> 


      test.aspx页面就是一个空页面,只不过需要在Page_Load中加入:

      Response.Expires = -1;

    保证不使用缓存,每次都能调用到这个页面。

      原理就是:设置Session的过期时间是一分钟,然后在每个页面上定时每30秒连接一次测试页面,保持Session有效,总共连60次,也就是30分钟。如果30分钟后用户还没有操作,Session就会过期。当然,如果用户直接关闭浏览器,那么一分钟后Session也会过期。这样就可以满足要求了。

  • 相关阅读:
    题目---结构体指针链表及迷宫问题
    题目---汉诺塔及AI代码及八皇后
    感想---如何去面试一个人?如何有效学习及提问的智慧。
    题目---统计学生成绩及一帮一及考试座位号
    题目---处理字符四题及预习题
    题目---改大写及自动售货机及删除指定元素
    第七周作业
    第六周作业
    第五周作业
    第四周作业
  • 原文地址:https://www.cnblogs.com/guoxiaowen/p/1040060.html
Copyright © 2020-2023  润新知