Thursday, February 28, 2008

2 UML tutorial

Keywords: UML 2.1




网上关于UML的文章很多, 但下面2篇文章很实用.


http://dn.codegear.com/article/31863(这个文章还带测试题目)


http://www.sparxsystems.com.au/resources/uml2_tutorial/index.html


点空间http://www.dotspace.idv.tw/ 也有比较好的文章.

Wednesday, February 27, 2008

how to Use Subversion with TortoiseSVN

Keywords: SVN, TortoiseSVN


how to Use Subversion with TortoiseSVN, visit http://www.codeproject.com/KB/books/Subversion_TortoiseSVN.aspx

SVN-How to set ignore-list

Keywords: Subversion, svn, tortoiseSVN


Subversion is a powerful source code control system. We can upload the source code into svn database. In many cases, we do not want to version some types files, such as bin folder and .user file. There are 2 ways to set ignore list.


For example, In .net development, some files need always ignore to verion such as bin obj *.suo *.obj *.pdb *.exe *.dll *.csproj.user


1. For one specific directory, we can use the tortoiseSVN to achieve it.


Steps:

Select one folder in explorer and then select the property menuitem. In Property/Subversion window, click the properties button,


And then click add button, select svn:ignore in the property combobox in subsequence window, Input the file extension in the textbox


2. Set global Ignore list.


Steps:


Find the config file for subversion, which is located in "\Documents and Settings\<user>\Application Data\Subversion" and the file name is Config with no extension.


To get it to ignore these directories or files, you need to uncomment or edit the global-ignores line. In mine, I have it set to:


global-ignores = bin obj *.suo *.obj *.pdb *.exe *.dll *.csproj.user


This will causes it to ignore the bin and obj sub-directories of a typical Visual Studio projects.



Monday, February 25, 2008

ruby dev tools

keywords: Ruby, JDT


One-Click Installer- Ruby interpretor and extenstion(Windows OS)


http://rubyforge.org/frs/?group_id=167


ActiveScriptRuby- Ruby interpretor and extenstion package(Windows OS)


http://arton.hp.infoseek.co.jp/indexj.html




RDE- Ruby Dev Eniviroment


http://homepage2.nifty.com/sakazuki/rde_en/index.html


RDT homepage


http://rubyeclipse.sourceforge.net/


Using the Ruby Development Tools plug-in for Eclipse


http://www.ibm.com/developerworks/opensource/library/os-rubyeclipse

Sunday, February 24, 2008

obfuscator .net Assembly

Keywords: Protection .net assembly


1. Aspose.Obfuscator is free, but use it at you own risk. http://www.aspose.com/Products/Aspose.Obfuscator/


2. CodeVeil is commercial software


http://www.xheo.com/products/codeveil/default.aspx


3. .NET Obfuscator community edition is free. But standard edition is not free.


http://www.preemptive.com/products/dotfuscator/index.html

Wednesday, February 20, 2008

open source net and security class library of c#

Keywords: C#, Opensource, Net library, Security Library, Certificate library


great opensource site http://www.mentalis.org/

interconvert byte[] and string and stream

keywords: C#, byte array, string, stream


stream和string和byte[]都是内存中的对象, 一般而言, string和byte[]都是轻量级的数据包装体, 在作layer间数据交换应优先使用它们, 因为它们占用更少的内存. 但它们本身的成员方法比较少, 尤其在持久化方面, 有可能需要借助Stream来完成, 那么怎样将string和byte[]转化成stream呢? 本文给出了一些代码. 有关不同类型stream相互转换, 可以参考另一篇文章(http://focuswindows.blogspot.com/2008/02/convert-filestream-fromto-memorystream.html).




/// <summary>
///如果你并不需要解析转换后的String, 那么可以将byte数组转换成Base64String.
/// 使用这个方法你不需要关心buffer数组中每个byte的编码, 统统都可以将它们转换成Base64String.
/// because Base64 store one char in 64 digits.
/// But the Base64 char is hard to recognized compared with the ASCII encode.
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public string ConvertBytesToBase64String(byte[] buffer)
{
return Convert.ToBase64String(buffer);
}


/// <summary>
/// 将一个Base64String转换成Byte[]
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public byte[] ConvertBase64StringToBytes(string str)
{
return Convert.FromBase64String(str);
}



/// <summary>
/// 将Stream转换为String
/// </summary>
/// <param name="ms"></param>
/// <returns></returns>
public string ConvertStreamIntoString(Stream ms)
{
//使用StreamReader应该是读取Stream最简单的方法
System.IO.StreamReader reader = new StreamReader(ms);
ms.Position = 0;
return reader.ReadToEnd();
}


/// <summary>
/// 将string转换成stream
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public MemoryStream ConvertStringToMemoryStream(string str)
{
MemoryStream ms=new MemoryStream() ;
//使用一个StreamWriter来将str写到一个MemoryStream
using (StreamWriter writer = new StreamWriter(ms))
{
writer.Write(str);
writer.Flush();
}
return ms;
}

Tuesday, February 19, 2008

Msn dev resources

Keywords: MSN


百步穿杨 http://www.blogjava.net/coacoa2008/archive/2007/12/04/165182.html


巴士飞扬 http://www.busfly.cn/

Develop MSN Robot By C#

this article is copied from http://www.busfly.cn/post/183.html


用.NET开发MSN聊天机器人 - MSN聊天机器人开发揭秘(收藏)

Wednesday, February 13, 2008

MSDN magazine reader--MSDNReader

Keywords: MSDNReader, MSDN



download: http://code.msdn.microsoft.com/msdnreader



This is a downloadable tool to allow you to read MSDN magazine - which is a great magazine to get up-to-date information on .NET.



Please download and share with your friends too. This requires .NET 3.0 to be installed on your system.

Show all C# exceptions by using Exception_Hunter of Red Gate software

Keywords: Exception, Exception Hunter, Red Gate


How to show all exceptions in you c# project before you release your product? It is important, because we will always leave some exceptions not handled. If you are in the situation, dont worry, you are not alone.


There is a tool can help you. The tool is Exception Hunter, It is a commerical software by Red Gate Software. I think the command line tool is more useful than the UI tool.


Command line usage:


"C:\Program Files\Red Gate\Exception Hunter 1\hunt.exe" /a:"D:\YourAssembly.Exe" /er:"Result_YourAssembly.html" /allpublicmethods

Sunday, February 3, 2008

the powerful DebugView

Keywords: capture debug output, Win32, .Net


DebugView is made by the famous Sysinternals company owned by Microsoft. 我们在程序中通常会有意用debug类(c#)输出一些调试信息, 或者我们要捕捉一些其他人开发的程序是否有异常, 都可以使用这个工具. 只要启动一个DebugView实例, 就可以监控所有程序的debug输出.


它不仅仅可以监视Windows和Console程序的debug, 而且可以监视Web程序的debug输出(需要在Web服务器上运行debugview).

How to test performance in C#

Keywords: Performace test, Win32, .Net Framework


In Win32,


Low resolution: GetTickCount() Api


High resolution: QueryPerformanceCounter() and QueryPerformanceFrequency()


In .Net


Low resolution: Enviroment.TickCount, the best resolution it will give you is 10 milliseconds.


High resolution: System.Diagnostics.Stopwatch class.


Stopwatch class usage:




private void btnPerformaceTest_Click(object sender, EventArgs e)
{
System.Diagnostics.Stopwatch sw = new Stopwatch();
sw.Start();
//Process1();
sw.Stop();
System.Console.WriteLine(sw.ElapsedMilliseconds);

sw.Reset();
sw.Start();
//Process2();
sw.Stop();
System.Console.WriteLine(sw.ElapsedMilliseconds);

sw.Reset();
sw.Start();
//Process3();
sw.Stop();
System.Console.WriteLine(sw.ElapsedMilliseconds);
}

how to read binary file and save it into xml

Keywords: CDATA node of xml, FileStream, MemoryStream, Base64String


In xml document, you can define CDATA node to store some large text string. There is a constraint in xml document, the xml document only can contain text string.


How to save image data or other binary data into xml?


We can convert the binary data into Base64String data, then we can store the Base64String data into xml document. We can use the following approach to achive.


Approach1: BinaryFile===>Byte[]===>Base64String===>CDATA


The following is pseudo code:



byte[] buffer=File.ReadAllBytes(string path);


string base64String= Convert.ToBase64String();


XmlCDATA=new XmlCDATA(base64String);


XmlDocument.AddChild(XmlCDATA);



How to restore the Base64String data into a FileStream?


It is easy to reach. The procedure is just reverse the above process.

Convert MemoryStream into FileStream

Keywords: C#, FileStream, MemoryStream


Sometimes, we need to convert FileStream into MemoryStream. And in other times, you need to convert memoryStream into fileStream because filestream is able to save to disk file.


How to convert string/byte[] into stream or convert stream into string/byte[], please refer another article. (http://focuswindows.blogspot.com/2008/02/interconvert-byte-and-string-and-stream.html)


How to convert MemoryStream into FileStream?


If you can solve the problem, it is will be easy to convert FileStream into MemoryStream because they are based the same parent class. There are 3 approaches to convert.


The 1st solution is use the loop strategy. This method can be used largely. Every time you read some bytes from Source_Stream into a buffer(buffer is byte array, it's length usually is 1k or 10k), then write the buffer into Target_Stream.


The 2nd solution is use MemoryStream.WriteTo(stream anotherStream). This have the highest performance, but Only MemoryStream has this method. (Because it do not need allocate additional memory for carriage buffer. It uses the MemoryStream object buffer property.)


The 3rd solution is read the whole Source_Stream into one single byte array, and then write byte array into Target_Stream. But it is not good solution, because you have to allocate too big memory for byte array.




public partial class Form1 : Form
{
public Form1()
{
//Add one textbox, named "textBox1"
//Add one button, named "btnTest"
InitializeComponent();
}

/// <summary>
/// Convert one MemoryStream object into FileStream Object.
/// Performance:
/// This method has the highest performance.
/// This method can used largely. It is also suited for convert other kind Stream into FileStream.
/// </summary>
/// <param name="ms"></param>
/// <param name="newFilePath"></param>
public void ConvertMemoryStreamToFileStream_1(MemoryStream ms, String newFilePath)
{
using (FileStream fs = File.OpenWrite(newFilePath))
{
const int blockSize = 1024;
byte[] buffer = new byte[blockSize];
int numBytes;
while ((numBytes = ms.Read(buffer, 0, blockSize)) > 0)
{
fs.Write(buffer, 0, numBytes);
}
}
}



/// <summary>
/// Convert one MemoryStream object into FileStream Object.
/// The method is so simple. but only MemoryStream has method WriteTo(Stream anotherStream)
/// Performance:
/// This method performace is worse than ConvertMemoryStreamToFileStream_1()
/// </summary>
/// <param name="ms"></param>
/// <param name="newFilePath"></param>
public void ConvertMemoryStreamToFileStream_2(MemoryStream ms, String newFilePath)
{
using (FileStream fs = File.OpenWrite(newFilePath))
{
ms.WriteTo(fs);
}
}



/// <summary>
/// Convert one MemoryStream object into FileStream Object.
/// Performace:
/// This method is the less effectively.
/// Because it have to allocate a great deal of memory to accommodate the whole MemoryStream all at once.
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public void ConvertMemoryStreamToFileStream_3(MemoryStream ms, String newFilePath)
{
// Allocate a large memory at first.
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);

using (FileStream fs = File.OpenWrite(newFilePath))
{
fs.Write(buffer, 0, (int)ms.Length);
}
}


/// <summary>
/// Create one MemoryStream object.
/// The result is not expanable MemoryStream.
/// Performance:
/// Create one MemoryStream object is fastest.
/// But read bytes from unexpansble memoryStream will consume more time. I do not know the reason.
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public MemoryStream CreateMemoryStream_1(string filePath)
{
//Step1: read whole FileStream into byte array.
byte[] buffer = System.IO.File.ReadAllBytes(filePath);


//Step2:convert byte array into MemoryStream.
MemoryStream ms1 = new MemoryStream(buffer);
return ms1;
}



/// <summary>
/// Create one MemoryStream object.
/// The result is not expanable MemoryStream.
/// Performace:
/// Create one MemoryStream object is slower
/// But read bytes from expansble memoryStream will consume less time. I do not know the reason.
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public MemoryStream CreateMemoryStream_2(string filePath)
{
int blockSize = 1024;
int bytesNum;
byte[] buffer = new byte[blockSize];
MemoryStream ms = new MemoryStream();
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
while ((bytesNum = fs.Read(buffer, 0, blockSize)) > 0)
{
ms.Write(buffer, 0, bytesNum);
}
}
return ms;
}


private void btnTest_Click(object sender, EventArgs e)
{
const string SourceFile = @"c:\Launch.wmv";
const string NewFile1 = @"c:\1.wmv";
const string NewFile2 = @"c:\2.wmv";
const string NewFile3 = @"c:\3.wmv";
if (File.Exists(NewFile1))
File.Delete(NewFile1);
if (File.Exists(NewFile2))
File.Delete(NewFile2);
if (File.Exists(NewFile3))
File.Delete(NewFile3);

textBox1.Clear() ;
Application.DoEvents();
MemoryStream ms = null;
try
{

System.Diagnostics.Stopwatch sw = new Stopwatch();
sw.Start();
ms = CreateMemoryStream_2(SourceFile);
if (ms != null)
{
sw.Stop();
textBox1.AppendText(sw.ElapsedMilliseconds.ToString() + "--CreateMemoryStream_2");
textBox1.AppendText(Environment.NewLine);

sw.Reset();
sw.Start();
ConvertMemoryStreamToFileStream_1(ms, NewFile1);

sw.Stop();
textBox1.AppendText( sw.ElapsedMilliseconds.ToString() + "--ConvertMemoryStreamToFileStream_1");
textBox1.AppendText(Environment.NewLine);

sw.Reset();
sw.Start();
ConvertMemoryStreamToFileStream_2(ms, NewFile2);
sw.Stop();
textBox1.AppendText( sw.ElapsedMilliseconds.ToString() + "--ConvertMemoryStreamToFileStream_2");
textBox1.AppendText(Environment.NewLine);

sw.Reset();
sw.Start();
ConvertMemoryStreamToFileStream_3(ms, NewFile3);
sw.Stop();
textBox1.AppendText( sw.ElapsedMilliseconds.ToString() + "--ConvertMemoryStreamToFileStream_3");
textBox1.AppendText(Environment.NewLine);
}
}
finally
{
if (ms != null)
ms.Close();
}
}
}

The performance test results:


In test case c:\Launch.wmv is an video file, its size is about 66M. if we use CreateMemoryStream_Method1() to create one unexpandable MemoryStream, the output result is:


212--CreateMemoryStream_1


968--ConvertMemoryStreamToFileStream_1


2016--ConvertMemoryStreamToFileStream_2


1929--ConvertMemoryStreamToFileStream_3


if we use CreateMemoryStream_Method2() to create an expandable MemoryStream, the output result is:


1011--CreateMemoryStream_2


1--ConvertMemoryStreamToFileStream_1


1619--ConvertMemoryStreamToFileStream_2


1225--ConvertMemoryStreamToFileStream_3

Friday, February 1, 2008

Using List<T>.Sort() and Find() by delegate

Keywords: C# Generic, List<T> class, Find, Sort, Comparison, Predicate


In List<T> class, Sort() method will perform to sort the list item. For List<string>, you can call Sort() method without argument. It will perform well. But if you sort List<Person> by using the same way, One error happened.


Why? Because the .Net Runtiime know how to compare toow string object, but it do not know how to compare two Person objects. In this situation, you will need define your comparison method. There is the same problem when using List.Find() method.


How to use List<T>.Sort()?


Refer to the List<T>.Sort source code. There are 4 override method, one of them is as follows,


public void Sort( Comparison <T> comparison);


And then refer to Comparison<T>, In System namespace


public delegate int Comparison <T>(T x, T y);


Ok, it is time to write code. You can define a static comparison method in PersonHelper class(one helper class for Person), it must follow the Comparison <T> delegate signature.


How to use List<T>.Find() ?


Look at the arguement of the Find(). This is also a delegate.


public T Find( Predicate <T> match);


and then refer to Predicate<T>, In System namespace


public delegate bool Predicate <T>(T obj);


We need pass one delegate object to Find() method, e.g CompareByNamePredicate. But the ComparePredicate() have only one argument, which is the enumerator of Generic List dictionary. How we specify the find condition, e.g, "TOM" for one Person name. We can encapsulate the CompareByNamePredicate method in one helper class. and we let one private variable of the helper class object to hold "TOM". Then we have Predicate method and Find condition. The subsequence is simple.


If you want use Helper class to achieve it, you can use anonymous delegate method. please refer to http://blogs.msdn.com/devdev/archive/2006/06/30/652802.aspx


The following code demo how to use helper class and anonymous delegate to approach the Find() and Sort() function.




/// <summary>
/// Main class, in this class we call the List.Find() and List.Sort().
/// </summary>
public partial class Form1 : Form
{
List<Person> m_ListPerson = new List<Person>();

public Form1()
{
InitializeComponent();
m_ListPerson.Add(new Person("c1"));
m_ListPerson.Add(new Person("a1"));
m_ListPerson.Add(new Person("TOM"));
}


/// <summary>
/// Use named delegate method to approach the sort function
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSort_Click(object sender, EventArgs e)
{
m_ListPerson.Sort(PersonHelper.CompareByName);
listBox1.Items.Clear();
foreach (Person p in m_ListPerson)
{
listBox1.Items.Add(p.FirstName);
}
}


/// <summary>
/// use anonymous delegate to approach the sort function
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSortByDelegate_Click(object sender, EventArgs e)
{
//public delegate int Comparison<T>(T x, T y);
m_ListPerson.Sort(delegate(Person p1, Person p2) { return string.Compare(p1.FirstName, p2.FirstName); });
listBox1.Items.Clear();
foreach (Person p in m_ListPerson)
{
listBox1.Items.Add(p.FirstName);
}
}


/// <summary>
/// Use Helper class and named method to approach the find function
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonFind_Click(object sender, EventArgs e)
{
PersonHelper personHelper = new PersonHelper();
personHelper.FirstName = "TOM";
Person person = m_ListPerson.Find(personHelper.CompareByNamePredicate);
listBox1.Items.Clear();
if (person != null)
{
listBox1.Items.Add(person.FirstName);
}
}

/// <summary>
/// use anonymous delegate to approach the find function
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonFindByDelegate_Click(object sender, EventArgs e)
{
///public delegate bool Predicate<T>(T obj);
Person person = m_ListPerson.Find(delegate(Person p) { return string.Equals(p.FirstName, "TOM"); });
listBox1.Items.Clear();
if (person != null)
{
listBox1.Items.Add(person.FirstName);
}
}
}


/// <summary>
/// This is a simple Class
/// </summary>
public class Person
{
private string m_FirstName;

public string FirstName
{
get { return m_FirstName; }
set { m_FirstName = value; }
}

public Person(string firstName)
{
this.m_FirstName = firstName;
}

}


/// <summary>
/// This is helper class, which provides sort and find capablity for Generic Collection Class
/// </summary>
public class PersonHelper
{

/// <summary>
/// implement the compare method, and it has the same signature with delegate Comparison
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
//public delegate int Comparison<T>(T x, T y);
public static int CompareByName(Person p1, Person p2)
{
return string.Compare(p1.FirstName, p2.FirstName);
}

string m_FirstName;

public string FirstName
{
get { return m_FirstName; }
set { m_FirstName = value; }
}


/// <summary>
/// /// implement the predicate method in order to find one person, and it has the same signature with delegate Predicate
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
///public delegate bool Predicate<T>(T obj);
public bool CompareByNamePredicate(Person p)
{
return string.Equals(p.FirstName, m_FirstName);
}
}