我的工作問題集(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":

CompanyAmount
W3Schools5500
IBM4500
W3Schools7100
SQL:
SELECT Company,SUM(Amount) FROM Sales
GROUP BY Company
HAVING SUM(Amount)>10000
结果:

CompanySUM(Amount)
W3Schools12600

 

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中加入事件:οnlοad="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也会过期。这样就可以满足要求了。

转载于:https://www.cnblogs.com/guoxiaowen/archive/2008/01/15/1040060.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值