??xml version="1.0" encoding="utf-8" standalone="yes"?>久久人人爽人人爽人人AV东京热,久久频这里精品99香蕉久,久久一区二区三区99 http://m.shnenglu.com/colys/category/3752.htmlLIFE AS CODE zh-cn Sat, 24 May 2008 11:33:23 GMT Sat, 24 May 2008 11:33:23 GMT 60 把多个文件写入到一个文件中dƈ能分?/title> http://m.shnenglu.com/colys/articles/33750.htmlcolys colys Mon, 08 Oct 2007 03:50:00 GMT http://m.shnenglu.com/colys/articles/33750.html http://m.shnenglu.com/colys/comments/33750.html http://m.shnenglu.com/colys/articles/33750.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/33750.html http://m.shnenglu.com/colys/services/trackbacks/33750.html 对于一个文件的dQ其实很单,是?font face="Times New Roman">FileStream q行Read 或?font face="Times New Roman">Writep了。但是如何把多个文g写入到同一个文Ӟ之后要能把这个文件进行还原成多个文g。那么光?font face="Times New Roman">FileStream?font face="Times New Roman">Read?font face="Times New Roman">WriteҎ是不够的Q首先你需要自行徏立文件烦引,来标明每个文件在当前文g的位|?/font>
那么最q作了一个简单的DEMO Q其中类的部分代码如下:
//------------------------------- Compose Files ----------------------------------
//--------------------------------------------------------------------------------
//---File:clsComposeFiles.cs
//---Description:This file is to show how-to compose multi-files into one file
// and decompose one file to multi-files.
//---Author:Knight
//---Date:May.16, 2006
//--------------------------------------------------------------------------------
//------------------------------{ Compose Files }---------------------------------
namespace ComposeFiles
{
using System;
using System.IO;
using System.Collections;
using System.Text;
/// <summary>
/// Summary description for clsComposeFiles.
/// </summary>
public class clsComposeFiles
{
private ArrayList arrFiles = new ArrayList();
public clsComposeFiles()
{
//
// TODO: Add constructor logic here
//
}
/// <summary>
/// Add a file to be composed
/// </summary>
/// <param name="sFileName"></param>
public void AddFile( string sFileName )
{
arrFiles.Add( sFileName );
}
/// <summary>
/// Compose files to the specific file
/// </summary>
/// <param name="sFileName"></param>
/// <returns></returns>
public bool ComposeFiles( string sFileName )
{
if( arrFiles.Count == 0 ) return false;
FileInfo fi = new FileInfo( sFileName );
// Open file to write
FileStream fsWriter = null;
try
{
if( !fi.Exists )
{
fsWriter = new FileStream(
sFileName,
FileMode.CreateNew,
FileAccess.ReadWrite,
FileShare.None );
}
else
fsWriter = new FileStream(
sFileName,
FileMode.Truncate,
FileAccess.ReadWrite,
FileShare.None );
}
catch(Exception err)
{
System.Diagnostics.Debug.WriteLine( err.Message );
return false;
}
byte[] bBuffer = null;
// Write files count
bBuffer = FileIndex.LongToBytes( arrFiles.Count );
fsWriter.Write( bBuffer, 0, 8 );
const long INDEX_START_POS = 8L;
// Init files index
FileIndex FI = new FileIndex();
for( int i = 0; i < arrFiles.Count; i++ )
fsWriter.Write( FileIndex.ConvertToBytes( ref FI ), 0, 32 );
long FILE_START_POS = INDEX_START_POS + 32 * arrFiles.Count;
long lCurFileStartPos = FILE_START_POS;
// Write every file
for( int i = 0; i < arrFiles.Count; i++ )
{
WriteFile( arrFiles[i].ToString(),
ref lCurFileStartPos,
INDEX_START_POS,
fsWriter,
i );
}
// Close stream
fsWriter.Close();
return true;
}
/// <summary>
/// Write file name and data into composed file
/// </summary>
/// <param name="sFileName"></param>
/// <param name="FileStartPos"></param>
/// <param name="IndexStartPos"></param>
/// <param name="fsWriter"></param>
/// <param name="Index"></param>
private void WriteFile(
string sFileName,
ref long FileStartPos,
long IndexStartPos,
FileStream fsWriter,
int Index )
{
FileInfo fi = new FileInfo( sFileName );
if( !fi.Exists ) return;
FileStream fsReader = null;
try
{
fsReader = new FileStream(
sFileName, FileMode.Open,
FileAccess.Read );
}
catch{ return;}
// Get file name
byte[] bFileName = Encoding.Unicode.GetBytes( fi.Name );
// Write file name
fsWriter.Write( bFileName, 0, bFileName.Length );
const int BUFFER_LENGTH = 1024;
byte[] bBuffer = new byte[BUFFER_LENGTH];
int nRealRead = 0;
// Write data using
do
{
// Read data from file
nRealRead = fsReader.Read( bBuffer, 0,
BUFFER_LENGTH );
// Write data
fsWriter.Write( bBuffer, 0, nRealRead );
}while( nRealRead > 0 );
// Close file reader
fsReader.Close();
FileIndex FINew = new FileIndex();
FINew.NameStartPos = FileStartPos;
FINew.NameLength = bFileName.Length;
FINew.FileStartPos = FileStartPos + bFileName.Length;
FINew.FileLength = fi.Length;
// Go back to file index position
fsWriter.Seek( IndexStartPos + Index * 32, SeekOrigin.Begin );
// Write file index info
fsWriter.Write( FileIndex.ConvertToBytes( ref FINew ), 0, 32 );
// Go back to file end
fsWriter.Seek( 0, SeekOrigin.End );
// Set file current position
FileStartPos += bFileName.Length + fi.Length;
}
/// <summary>
/// Decompose file to multi files into specific directory
/// </summary>
/// <param name="sFileName"></param>
/// <param name="sDestDir"></param>
/// <returns></returns>
public bool DecomposeFile( string sFileName, string sDestDir )
{
FileInfo fi = new FileInfo( sFileName );
if( !fi.Exists ) return false;
FileStream fsReader = null;
try
{
fsReader = new FileStream(
sFileName, FileMode.Open,
FileAccess.Read );
}
catch{ return false;}
// Read file count
byte[] bFileCount = new byte[8];
int nRealRead = 0;
nRealRead = fsReader.Read( bFileCount, 0, 8 );
if( nRealRead != 8 )
{
fsReader.Close();
return false;
}
long lFileCount = FileIndex.BytesToLong( bFileCount );
if( lFileCount > 0 )
{
//Init file index array
FileIndex[] fiArray = new FileIndex[lFileCount];
byte[] bFileIndex = new byte[32];
for( int i = 0; i < lFileCount; i++ )
{
fsReader.Read( bFileIndex, 0, 32 );
fiArray[i] = FileIndex.ConvertToFileIndex( bFileIndex );
}
if( sDestDir[ sDestDir.Length - 1] != '\\' )
sDestDir += "\\";
// Save every file into current directory
for( int i = 0; i < fiArray.Length; i++ )
{
SaveFile( fsReader,
ref fiArray[i],
sDestDir );
}
}
// Close file reader
fsReader.Close();
return true;
}
/// <summary>
/// Save every file into directory
/// </summary>
/// <param name="fsReader"></param>
/// <param name="FI"></param>
/// <param name="sDestDir"></param>
private void SaveFile(
FileStream fsReader,
ref FileIndex FI,
string sDestDir )
{
// Read file name
byte[] bFileName = new byte[ FI.NameLength ];
int nRealRead = fsReader.Read( bFileName, 0, bFileName.Length );
if( nRealRead != bFileName.Length ) return;
string sFileName = Encoding.Unicode.GetString( bFileName );
sFileName = sDestDir + sFileName;
FileInfo fi = new FileInfo( sFileName );
// Open file to write
FileStream fsWriter = null;
try
{
if( !fi.Exists )
{
fsWriter = new FileStream(
sFileName,
FileMode.CreateNew,
FileAccess.ReadWrite,
FileShare.None );
}
else
fsWriter = new FileStream(
sFileName,
FileMode.Truncate,
FileAccess.ReadWrite,
FileShare.None );
}
catch(Exception err){
System.Diagnostics.Debug.WriteLine( err.Message );
return;
}
// Init buffer
const int BUFFER_LENGTH = 1024;
byte[] bBuffer = new byte[BUFFER_LENGTH];
long lLeft = FI.FileLength;
// Copy file
do
{
if( lLeft > BUFFER_LENGTH )
{
fsReader.Read( bBuffer, 0, BUFFER_LENGTH );
fsWriter.Write( bBuffer, 0, BUFFER_LENGTH );
lLeft -= BUFFER_LENGTH;
}
else
{
nRealRead = fsReader.Read( bBuffer, 0, (int)lLeft );
fsWriter.Write( bBuffer, 0, nRealRead );
lLeft -= nRealRead;
}
}
while( lLeft > 0 );
// close file writer
fsWriter.Close();
}
}
/// <summary>
/// File index data structure
/// </summary>
public struct FileIndex
{
public long NameStartPos;
public long NameLength;
public long FileStartPos;
public long FileLength;
public static byte[] ConvertToBytes( ref FileIndex FI )
{
byte[] bData = new byte[32];
Array.Copy( LongToBytes( FI.NameStartPos ), 0, bData, 0, 8 );
Array.Copy( LongToBytes( FI.NameLength ), 0, bData, 8, 8 );
Array.Copy( LongToBytes( FI.FileStartPos ), 0, bData, 16, 8 );
Array.Copy( LongToBytes( FI.FileLength ), 0, bData, 24, 8 );
return bData;
}
public static byte[] LongToBytes( long lValue )
{
byte[] bData = new byte[8];
bData[0] = (byte)( ( lValue >> 56 ) & 0xFF);
bData[1] = (byte)( ( lValue >> 48 ) & 0xFF);
bData[2] = (byte)( ( lValue >> 40 ) & 0xFF);
bData[3] = (byte)( ( lValue >> 32 ) & 0xFF);
bData[4] = (byte)( ( lValue >> 24 ) & 0xFF);
bData[5] = (byte)( ( lValue >> 16 ) & 0xFF);
bData[6] = (byte)( ( lValue >> 8 ) & 0xFF);
bData[7] = (byte)(lValue & 0xFF);
return bData;
}
public static FileIndex ConvertToFileIndex( byte[] bData )
{
if( bData == null || bData.Length != 32 )
throw new Exception( "Invalid parameters!" );
FileIndex FI = new FileIndex();
byte[] bBuffer = new byte[8];
Array.Copy( bData, 0, bBuffer, 0, 8 );
FI.NameStartPos = BytesToLong( bBuffer );
Array.Copy( bData, 8, bBuffer, 0, 8 );
FI.NameLength = BytesToLong( bBuffer );
Array.Copy( bData, 16, bBuffer, 0, 8 );
FI.FileStartPos = BytesToLong( bBuffer );
Array.Copy( bData, 24, bBuffer, 0, 8 );
FI.FileLength = BytesToLong( bBuffer );
return FI;
}
public static long BytesToLong( byte[] bData )
{
if( bData == null || bData.Length != 8 )
throw new Exception( "Invalid parameters!" );
long lngValue = 0;
lngValue += bData[0];
lngValue = ( lngValue << 8 );
lngValue += bData[1];
lngValue = ( lngValue << 8 );
lngValue += bData[2];
lngValue = ( lngValue << 8 );
lngValue += bData[3];
lngValue = ( lngValue << 8 );
lngValue += bData[4];
lngValue = ( lngValue << 8 );
lngValue += bData[5];
lngValue = ( lngValue << 8 );
lngValue += bData[6];
lngValue = ( lngValue << 8 );
lngValue += bData[7];
return lngValue;
}
}
}
其中cȝ操作参看clsComposeFiles q个c,而文件烦引结构参?font face="Times New Roman">FileIndex q个Structure ?/font>
之后的调用就很简单,例如Q?/font>
合成文gQ?/font>
clsComposeFiles myComposeFiles = new clsComposeFiles();
myComposeFiles.AddFile( @"D:\Ship.exe" );
myComposeFiles.AddFile( @"D:\LoginPage.JPG" );
myComposeFiles.ComposeFiles( @"D:\Ship.dat" );
分解文gQ?/font>
clsComposeFiles myComposeFiles = new clsComposeFiles();
myComposeFiles.DecomposeFile( @"D:\Ship.dat", @"E:\" );
]]>利用客户端缓存对|站q行优化[转] http://m.shnenglu.com/colys/articles/32840.htmlcolys colys Tue, 25 Sep 2007 05:23:00 GMT http://m.shnenglu.com/colys/articles/32840.html http://m.shnenglu.com/colys/comments/32840.html http://m.shnenglu.com/colys/articles/32840.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/32840.html http://m.shnenglu.com/colys/services/trackbacks/32840.html 介绍
你的|站在ƈ发访问很大ƈ且无法承受压力的情况?你会选择如何优化?
很多人首先会想从服务器缓存方面着手对E序q行优化,许多不同的服务器~存
方式都有他们自己的特?像我曄参与的一些项目中,Ҏ~存的命中率不同使用q?Com+/Enterprise Libiary
Caching/Windows服务,静态文件等方式的服务器端缓存和 HTTP Compression 技
?但客L~存往往却被Z忽略?即服务器的~存让你的页面访问v来非常地?但她依然需要依赖浏览器下蝲q输?而当你加入客L~存?会给?
带来非常多的好处.因ؓ她可以对站点中访问最频繁的页q行~存充分地提?Web
服务器的吞吐量(通常以每U的h数计)以提升应用程序性能和可伸羃性?nbsp;
一个在U购物调查显C,大多Ch愿意d店排队,但在在线购物时却不愿意等待。Websense调查公司U多?0%的上|者表CZ愿意在页面读取上过10U钟。超q?0%的h会因Z途速度q慢而取消当前的订单?
基础知识
1) 什么是”Last-Modified”?
在浏览器W一ơ请求某一个URLӞ服务器端的返回状态会?00Q内Ҏ你请求的资源Q同时有一个Last-Modified的属性标记此文g在服务期端最后被修改的时_格式cMq样Q?nbsp;
Last-Modified: Fri, 12 May 2006 18:53:33 GMT
客户端第二次h此URLӞҎ HTTP 协议的规定,览器会向服务器传?If-Modified-Since 报头Q询问该旉之后文g是否有被修改q:
If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
如果服务器端的资源没有变化,则自动返?HTTP 304 QNot
Changed.Q状态码Q内容ؓI,q样p省了传输数据量。当服务器端代码发生改变或者重启服务器Ӟ则重新发源,q回和第一ơ请求时cM?
从而保证不向客L重复发出资源Q也保证当服务器有变化时Q客L能够得到最新的资源?nbsp;
2) 什么是”Etag”?
HTTP 协议规格说明定义ETag?#8220;被请求变量的实体?#8221; Q?a target="_blank">参见 —?章节 14.19Q?另一U说法是QETag是一个可以与Web资源兌的记PtokenQ。典型的Web资源可以一个Web,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,q在HTTP响应头中其传送到客户端,以下是服务器端返回的格式Q?nbsp;
ETag: "50b1c1d4f775c61:df3"
客户端的查询更新格式是这LQ?nbsp;
If-None-Match: W/"50b1c1d4f775c61:df3"
如果ETag没改变,则返回状?04然后不返回,q也和Last-Modified一栗本人测试Etag主要在断点下载时比较有用?br>
Last-Modified和Etags如何帮助提高性能?
聪明的开发者会把Last-Modified
和ETagsh的http报头一起用,q样可利用客LQ例如浏览器Q的~存。因为服务器首先产生
Last-Modified/Etag标记Q服务器可在E后使用它来判断面是否已经被修攏V本质上Q客L通过该记号传回服务器要求服务器验证Ӟ?
LQ缓存?nbsp;
q程如下:
1. 客户端请求一个页面(AQ?nbsp;
2. 服务器返回页面AQƈ在给A加上一个Last-Modified/ETag?nbsp;
3. 客户端展现该面Qƈ页面连同Last-Modified/ETag一L存?nbsp;
4. 客户再次h面AQƈ上ơ请求时服务器返回的Last-Modified/ETag一起传递给服务器?nbsp;
5. 服务器检查该Last-Modified或ETagQƈ判断面自上ơ客Lh之后q未被修改,直接q回响应304和一个空的响应体?br>
CZ代码
下面的例子描q如何用服务器端代码去操作客户端缓?
// 默认~存的秒?/span> int secondsTime = 100 ; // 判断最后修Ҏ间是否在要求的时间内 // 如果服务器端的文件没有被修改q,则返回状态是304Q内容ؓI,q样p省了传输数据量。如果服务器端的文g被修改过Q则q回和第一ơ请求时cM?/span> if (request.Headers[ " If-Modified-Since " ] != null && TimeSpan.FromTicks(DateTime.Now.Ticks - DateTime.Parse(request.Headers[ " If-Modified-Since " ]).Ticks).Seconds < secondsTime) { // 试代码,在这里会发现,当浏览器q回304状态时,下面的日期ƈ不会输出 Response.Write(DateTime.Now); response.StatusCode = 304 ; response.Headers.Add( " Content-Encoding " , " gzip " ); response.StatusDescription = " Not Modified " ; } else { // 输出当前旉 Response.Write(DateTime.Now); // 讄客户端缓存状?/span> SetClientCaching(response, DateTime.Now); } #region SetClientCaching.. /// <summary> /// 讄客户端缓存状?br> /// </summary> /// <param name="response"></param> /// <param name="lastModified"></param> private void SetClientCaching(HttpResponse response, DateTime lastModified) { response.Cache.SetETag(lastModified.Ticks.ToString()); response.Cache.SetLastModified(lastModified); // public 以指定响应能由客L和共享(代理Q缓存进行缓存?/span> response.Cache.SetCacheability(HttpCacheability.Public); // 是允许文在被视为陈旧之前存在的最长绝Ҏ间?/span> response.Cache.SetMaxAge( new TimeSpan( 7 , 0 , 0 , 0 )); // 缓存过期从l对旉讄为可调时?/span> response.Cache.SetSlidingExpiration( true ); } #endregion
如果你的~存是基于文件的方式,如XML或http中的.ashx处理,也可以用下面的Z文g方式的客L~存:
#region SetFileCaching.. /// <summary> /// Z文g方式讄客户端缓?br> /// </summary> /// <param name="fileName"></param> private void SetFileCaching(HttpResponse response, string fileName) { response.AddFileDependency(fileName); // Z处理E序文g依赖的旉戌|?nbsp;ETag HTTP 标头?nbsp; response.Cache.SetETagFromFileDependencies(); // Z处理E序文g依赖的旉戌|?nbsp;Last-Modified HTTP 标头?/span> response.Cache.SetLastModifiedFromFileDependencies(); response.Cache.SetCacheability(HttpCacheability.Public); response.Cache.SetMaxAge( new TimeSpan( 7 , 0 , 0 , 0 )); response.Cache.SetSlidingExpiration( true ); } #endregion
使用后的效果如下图所C?
上图所使用的工h在IE下运行的HttpWatchPro ,在Firefox下可以?a target="_blank" >FireBug+YSlow q行试.
YSlow是徏立在FireBug基础上运行的一个小工具,它可以对你的|页q行分析Z么缓?q给分和~慢的原?q个工具来自Yahoo的研发团?所以规则也是Yahoo制定?
l论
我们已经看了如何使用客户端缓存减带宽和计算的方?如前所q?如果能正
合理的利用各种不同的缓?他们会给你带来很多的好处.我希望本文已Z当下或将来基于Web的项目提供了_食粮Qƈ正确地在底层利用Last-
Modified和ETag响应头去优化你的目?nbsp;
参考资?
301怹重定向实现方式及302重定?/a>
理解ASP.NET与客L~存之HTTP协议
如何利用客户端缓存对|站q行优化? 原文地址Q?a title="http://www.cnblogs.com/lion.net/archive/2007/09/24/904717.html" >http://www.cnblogs.com/lion.net/archive/2007/09/24/904717.html ]]> nhibernate入门pd: many-to-many映射[转] http://m.shnenglu.com/colys/articles/32461.htmlcolys colys Wed, 19 Sep 2007 03:31:00 GMT http://m.shnenglu.com/colys/articles/32461.html http://m.shnenglu.com/colys/comments/32461.html http://m.shnenglu.com/colys/articles/32461.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/32461.html http://m.shnenglu.com/colys/services/trackbacks/32461.html 多对多关pd数据库也是比较常见的Q它通过一个中间表两个主表关联v来?br>下面来看看多对多兌在nh的实玎ͼCZ是一个User和Group之间的多对多兌?br> 先来看看Usercȝ映射信息: 在多对多定义中,定义了中间表为UserGroupsQ此表只有两个字D:user_id和group_idQ用于关联Users和Groups表?br> User的定义:
public class User
{ public User() { } public int UserId {
get { return userId; } set { userId = value; } } public
int Name { get { return name; } set { name = value;
} } public IDictionary Groups { get { return
groups; } set { groups = value; } } private int
userId; private string name; private IDictionary groups = new
Hashtable(); } //class
User
q里用一个数据字典IDictionary对角来保存组对象?br> 再来看看Groupcȝ映射信息Q?br> q里many-to-many的定义和UsercL信息中的差不多?br> l类的定义:
public class Group
{ public Group() { } public int GroupId
{ get { return groupId; } set { groupId = value; }
} public int Name { get { return name; } set {
name = value; } } public int Description { get {
return description; } set { description = value; } }
public IDictionary Users { get { return users; } set {
users = value; } } private int groupId; private string
name; private IDictionary users = new Hashtable(); } //class
Group
注意Q多对多没有L之分Q保存时的两辚w要save! 下面l出部分试代码?br>
public TestCreate()
{ User user1 = new User(); user1.Name = "test1"; User user2 =
new User(); user2.Name = "test2"; Group group1 = new
Group(); group1.Name = "group1"; Group group2 = new Group();
group2.Name = "group2"; user1.Groups.Add( group2, group2 );
user2.Groups.Add( group1. group1 ); group1.Users.Add( user2, user2
); group2.Users.Add( user1, user1 ); ITransactioin trans =
null; try { trans = session.BeginTransaction();
Session.Save( user1 ); Session.Save( user2 ); Session.Save(
group1 ); Session.Save( group2 ); trans.Commit();
} catch ( Exception e ) { if ( trans != null )
trans.Rollback(); throw e; } finally {
session.Close();
} }
以上试代码中session的相x作请查看相关文档?br> 在实际应用中Q我较少使用many-to-many映射Q当然这要从性能和实际需要考虑?br>我的做法是一个elements来取得所有关联的identity,
然后在需要的时候才加蝲对象Q有点类似lazy,
但lazy有一个问题,是session必须没有被释放,q在分层开发中较难办到?br> 原文:http://www.seaskyer.net/Index/Catalog44/182.html
]]> 分散数据库压?分表处理设计思想和实?/title> http://m.shnenglu.com/colys/articles/32397.htmlcolys colys Tue, 18 Sep 2007 01:51:00 GMT http://m.shnenglu.com/colys/articles/32397.html http://m.shnenglu.com/colys/comments/32397.html http://m.shnenglu.com/colys/articles/32397.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/32397.html http://m.shnenglu.com/colys/services/trackbacks/32397.html 一、概q?/strong>
分表是个目前是比较炒的比较行的概念,特别是在大负载的情况下,分表是一个良好分散数据库压力的好Ҏ?/div>
首先要了解ؓ什么要分表Q分表的好处是什么。我们先来大概了解以下一个数据库执行SQL的过E:
接收到SQL --> 攑օSQL执行队列 --> 使用分析器分解SQL --> 按照分析l果q行数据的提取或者修?--> q回处理l果
当然Q这个流E图不一定正,q只是我自己主观意识上这么我认ؓ。那么这个处理过E当中,最Ҏ出现问题的是什么?是_如果前一个SQL?
有执行完毕的话,后面的SQL是不会执行的Q因Zؓ了保证数据的完整性,必须Ҏ据表文gq行锁定Q包括共享锁和独享锁两种锁定。共享锁是在锁定的期_
其它U程也可以访问这个数据文Ӟ但是不允怿Ҏ作,相应的,独n锁就是整个文件就是归一个线E所有,其它U程无法讉Kq个数据文g。一般MySQL?
最快的存储引擎MyISAMQ它是基于表锁定的,是说如果一锁定的话Q那么整个数据文件外部都无法讉KQ必ȝ前一个操作完成后Q才能接收下一个操作,
那么在这个前一个操作没有执行完成,后一个操作等待在队列里无法执行的情况叫做dQ一般我们通俗意义上叫?#8220;锁表”?/div>
锁表直接D的后果是什么?是大量的SQL无法立即执行Q必ȝ队列前面的SQL全部执行完毕才能l箋执行。这个无法执行的SQL׃D没有l果Q或者gq严重,影响用户体验?/div>
特别是对于一些用比较频J的表,比如SNSpȝ中的用户信息表、论坛系l中的帖子表{等Q都是访问量大很大的表,Z保证数据的快速提取返回给用户Q必M用一些处理方式来解决q个问题Q这个就是我今天要聊到的分表技术?/div>
分表技术顾名思义Q就是把若干个存储相同类型数据的表分成几个表分表存储Q在提取数据的时候,不同的用戯问不同的表,互不冲突Q减锁表的?
率。比如,目前保存用户分表有两个表Q一个是user_1表,q有一个是 user_2 表,两个表保存了不同的用户信息,user_1
保存了前10万的用户信息Quser_2保存了后10万名用户的信息,现在如果同时查询用户 heiyeluren1 ?heiyeluren2
q个两个用户Q那么就是分表从不同的表提取出来Q减锁表的可能?/div>
我下面要讲述的两U分表方法我自己都没有实验过Q不保证准确能用Q只是提供一个设计思\。下面关于分表的例子我假设是在一个脓吧系l的基础上来q行处理和构建的。(如果没有用过贴吧的用戯紧Google一下)
二、基于基表的分表处理
q个Z基础表的分表处理方式大致的思想是Q一个主要表Q保存了所有的基本信息Q如果某个项目需要找到它所存储的表Q那么必Mq个基础表中
查找出对应的表名{项目,好直接访问这个表。如果觉得这个基表速度不够快,可以完全把整个基表保存在~存或者内存中Q方便有效的查询?/div>
我们Z贴吧的情况,构徏假设如下?张表Q?/div>
1. 贴吧版块? 保存贴吧中版块的信息
2. 贴吧主题表:保存贴吧中版块中的主题信息,用于览
3. 贴吧回复表:保存主题的原始内容和回复内容
“贴吧版块?#8221;包含如下字段Q?/div>
版块ID board_id int(10)
版块名称 board_name char(50)
子表ID table_id smallint(5)
产生旉 created datetime
“贴吧主题?#8221;包含如下字段Q?/div>
主题ID topic_id int(10)
主题名称 topic_name char(255)
版块ID board_id int(10)
创徏旉 created datetime
“贴吧回复?#8221;的字D如下:
回复ID reply_id int(10)
回复内容 reply_text text
主题ID topic_id int(10)
版块ID board_id int(10)
创徏旉 created datetime
那么上面保存了我们整个脓吧中的表l构信息Q三个表对应的关pLQ?/div>
版块 --> 多个主题
主题 --> 多个回复
那么是_表文件大的关系是:
版块表文?< 主题表文?< 回复表文?/div>
所以基本可以确定需要对主题表和回复表进行分表,已增加我们数据检索查询更Ҏ候的速度和性能?/div>
看了上面的表l构Q会明显发现Q在“版块?#8221;中保存了一?table_id"字段Q这个字D就是用于保存一个版块对应的主题和回复都是分表保存在什么表里的?/div>
比如我们有一个叫?#8220;PHP”的脓吧,board_id?Q子表ID也是1Q那么这条记录就是:
board_id | board_name | table_id | created
1 | PHP | 1 | 2007-01-19 00:30:12
相应的,如果我需要提?#8220;PHP”吧里的所有主题,那么必L照表里保存的table_id来组合一个存储了主题的表名称Q比如我们主题表的前~?#8220;topic_”Q那么组合出?#8220;PHP”吧对应的主题表应该是Q?#8220;topic_1”Q那么我们执行:
Select * FROM topic_1 Where board_id = 1 orDER BY topic_id DESC LIMIT 10
q样p够获取这个主题下面回复列表,方便我们q行查看Q如果需要查看某个主题下面的回复Q我们可以l用版块表中保存的“table_id”来进行查询。比如我们回复表的前~?#8220;reply_”Q那么就可以l合?#8220;PHP”吧的ID?的主题的回复Q?/div>
Select * FROM reply_1 Where topic_id = 1 orDER BY reply_id DESC LIMIT 10
q里Q我们能够清晰的看到Q其实我们这里用了基础表,基础表就是我们的版块表。那么相应的Q肯定会_基础表的数据量大了以后如何保证它的速度和效率?
当然Q我们就必须使得q个基础表保持最好的速度和性能Q比如,可以采用MySQL的内存表来存储,或者保存在内存当中Q比如Memcache之类的内存缓存等{,可以按照实际情况来进行调整?/div>
一般基于基表的分表机制在SNS、交友、论坛等Web2.0|站中是个比较不错的解决ҎQ在q些|站中,完全可以单独使用一个表来来保存基本标识和目标表之间的关pR用表保存对应关系的好处是以后扩展非常方便Q只需要增加一个表记录?/div>
?strong> 优势 】增加删除节炚w常方便,为后期升U维护带来很大便?/div>
?strong> 劣势 】需要增加表或者对某一个表q行操作Q还是无法离开数据库,会生瓶?/div>
三、基?/strong> Hash 法的分表处?/strong>
我们知道Hash表就是通过某个Ҏ的Hash法计算出的一个|q个值必L惟一的,q且能够使用q个计算出来的值查扑ֈ需要的|q个叫做哈希表?/div>
我们在分表里的hash法跟这个思想cMQ通过一个原始目标的ID或者名U通过一定的hash法计算出数据存储表的表名,然后讉K相应的表?/div>
l箋拿上面的贴吧来说Q每个脓吧有版块名称和版块IDQ那么这两项值是固定的,q且是惟一的,那么我们可以考虑通过对这两项g的一进行一些运得Z个目标表的名U?/div>
现在假如我们针对我们q个贴吧pȝQ假讄l最大允?亿条数据Q考虑每个表保?00万条记录Q那么整个系l就不超q?00个表p够容U뀂按照这个标准,我们假设在脓吧的版块ID上进行hashQ获得一个key|q个值就是我们的表名Q然后访问相应的表?/div>
我们构造一个简单的hash法Q?/div>
function get_hash($id){
$str = bin2hex($id);
$hash = substr($str, 0, 4);
if (strlen($hash)<4){
$hash = str_pad($hash, 4, "0");
}
return $hash;
}
法大致是传入一个版块ID|然后函数q回一?位的字符Ԍ如果字符串长度不够,使用0q行补全?/div>
比如Qget_hash(1)Q输出的l果?#8220;3100”Q输入:get_hash(23819)Q得到的l果是:3233Q那么我们经q简单的跟表前缀l合Q就能够讉Kq个表了。那么我们需要访问ID?的内Ҏ候哦Q组合的表将是:topic_3100、reply_3100Q那么就可以直接对目标表q行讉K了?/div>
当然Q用hash法后,有部分数据是可能在同一个表的,q一点跟hash表不同,hash表是量解决冲突Q我们这里不需要,当然同样需要预和分析表数据可能保存的表名?/div>
如果需要存储的数据更多Q同LQ可以对版块的名字进行hash操作Q比如也是上面的二进制{换成十六q制Q因为汉字比数字和字母要多很多,那么重复几率更小Q但是可能组合成的表更多了Q相应就必须考虑一些其它的问题?/div>
归根l底Q用hash方式的话必须选择一个好的hash法Q才能生成更多的表,然数据查询的更迅速?/div>
?strong> 优点hash法直接得出目标表名Uͼ效率很高 】通过
?strong> 劣势 】扩展性比较差Q选择了一个hash法Q定义了多少数据量,以后只能在这个数据量上跑Q不能超q过q个数据量,可扩展性稍?/div>
四、其它问?/strong>
1. 搜烦问题
现在我们已经q行分表了,那么无法直接对表进行搜索,因ؓ你无法对可能pȝ中已l存在的几十或者几百个表进行检索,所以搜索必d助W三方的lg来进行,比如Lucene作ؓ站内搜烦引擎是个不错的选择?/div>
2. 表文仉?/strong>
我们知道MySQL的MyISAM引擎每个表都会生成三个文Ӟ*.frm?.MYD?.MYI
三个文gQ分表用来保存表l构、表数据和表索引。Linux下面每个目录下的文g数量最好不要超q?000个,不然索数据将更慢Q那么每个表都会生成?
个文Ӟ相应的如果分表超q?00个表Q那么将索非常慢Q所以这时候就必须再进行分Q比如在q行数据库的分离?/div>
使用基础表,我们可以新增加一个字D,用来保存q个表保存在什么数据。用Hash的方式,我们必须截取hashgW几位来作ؓ数据库的名字。这P完好的解册个问题?/div>
五、ȝ
在大负蝲应用当中Q数据库一直是个很重要的瓶颈,必须要突_本文讲解了两U分表的方式Q希望对很多够有启发的作用。当Ӟ本文代码和设x有经qQ何代码测试,所以无法保证设计的完全准确实用Q具体还是需要读者在使用q程当中认真分析实施?/div>
]]>
非递归遍历文g?/title> http://m.shnenglu.com/colys/articles/32395.htmlcolys colys Tue, 18 Sep 2007 01:39:00 GMT http://m.shnenglu.com/colys/articles/32395.html http://m.shnenglu.com/colys/comments/32395.html http://m.shnenglu.com/colys/articles/32395.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/32395.html http://m.shnenglu.com/colys/services/trackbacks/32395.html /// <summary> /// 非递归遍历文g?br> /// </summary> public class UnRecursionDirectoryReader { public event UnRecursionRead OnUnRecursionItemRead; public event UnRecursionRead OnUnRecursionDequeue; public event UnRecursionRead OnUnRecursionEnqueue; public void Read( string Path) { string P_Path = Path; Queue < string > source = new Queue < string > (); bool IsHasChild = true ; // 是否有子文g?nbsp; while (IsHasChild) { string [] Directorys = System.IO.Directory.GetDirectories(P_Path); string [] Files = System.IO.Directory.GetFiles(P_Path); foreach ( string dir in Directorys) { source.Enqueue(dir); // 入队?开始访问文件夹 if (OnUnRecursionEnqueue != null ) OnUnRecursionEnqueue(dir, P_Path); } foreach ( string file in Files) { if (OnUnRecursionItemRead != null ) OnUnRecursionItemRead(file, P_Path); // 讉K文g } if (source.Count > 0 ) { string OldPath = P_Path; P_Path = source.Dequeue(); // 出队?更换文g?/span> if (OnUnRecursionDequeue != null ) OnUnRecursionDequeue(P_Path, OldPath); } else { IsHasChild = false ; } } } } demo:
TreeNode TargetNode = null ; // 指向treeview的结?/span> Queue < TreeNode > TreeQueue = new Queue < TreeNode > (); // 临时存放 private void read() { CYS.UnRecursionDirectoryReader TreeReader = new CYS.UnRecursionDirectoryReader(); TreeReader.OnUnRecursionDequeue += new CYS.UnRecursionRead(TreeReader_OnUnRecursionDequeue); TreeReader.OnUnRecursionEnqueue += new CYS.UnRecursionRead(TreeReader_OnUnRecursionEnqueue); TreeReader.OnUnRecursionItemRead += new CYS.UnRecursionRead(TreeReader_OnUnRecursionItemRead); TreeReader.Read(AppRoot); } private void TreeReader_OnUnRecursionItemRead( string DireName, string Parent) { TargetNode.Nodes.Add(System.IO.Path.GetFileName(DireName)); } private void TreeReader_OnUnRecursionDequeue( string DireName, string Parent) { TargetNode = TreeQueue.Dequeue(); } private void TreeReader_OnUnRecursionEnqueue( string DireName, string Parent) { TreeNode Node = new TreeNode(System.IO.Path.GetFileName(DireName)); TargetNode.Nodes.Add(Node); TreeQueue.Enqueue(Node); }
]]>
如何获得数据库里所有表的名字(SQL+C#Q? http://m.shnenglu.com/colys/articles/30745.htmlcolys colys Fri, 24 Aug 2007 01:34:00 GMT http://m.shnenglu.com/colys/articles/30745.html http://m.shnenglu.com/colys/comments/30745.html http://m.shnenglu.com/colys/articles/30745.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/30745.html http://m.shnenglu.com/colys/services/trackbacks/30745.html qx我们操作比较多的都是表里的数据,也许H然有一天会需要把所有表的名字都列出来看一看——比如,你的论坛是按每个版块一个表来管理的Q这时候你要在首页列出各版块的名字。应该怎么办呢Q?/p>
肯定得用SELECT?#8230;…但我们^时用SELECT操作的数据都是表里的数据Q表的名字ƈ不是表的数据Q这可怎么办呢Q?/p>
你可能会惻I“功能强大的SQL Server不会q这么简单的功能都实C了吧Q一定会把所有表的名字存储在某个表里……”注意啦!在这儿我要小地h一下概念了——视图(ViewQ也是一U?#8220;?#8221;Q只不过它是由固定查询Ş成的一U?#8220;虚拟?#8221;?/p>
OKQ你猜对啦!由SQL Server理的每个数据库里都有一个名为sysobjects的视图,它是systemU别的,所以它的全限定名是——sys.sysobjects
你可能又会问Q?#8220;Z么不是sys.tables而是sys.objects呢?”问的好!因ؓq张表里存储的可不光是数据库里的表,它存储的是一个数据库中所有的“对象”——杂七杂八包括了表的主键、存储过E、触发器{等Q?font color=#0000ff>一共是24U?/font>——表QTableQ确切地说是“用户自定义表”Q只是这24U对象中的一U?/p>
剩下的事?#8230;…吼吼……
执行下面的查询语句,可以得到所有包含在sys.sysobjects视图里的数据
USE AdventureWorks SELECT * FROM sys.sysobjects GO
得出数据后,h意名为type的列——这一列标明了对象的类型,也就是前面提到的24U。在q里Q我用一个表格把它们列出来:
AF = Aggregate function (CLR)
C = CHECK constraint
D = DEFAULT (constraint or stand-alone)
F = FOREIGN KEY constraint
FN = SQL scalar function
FS = Assembly (CLR) scalar function
FT = Assembly (CLR) table-valued function
IF = SQL inline table-valued function
IT = Internal table
P = SQL stored procedure
PC = Assembly (CLR) stored procedure
PK = PRIMARY KEY constraint
R = Rule (old-style, stand-alone)
RF = Replication-filter-procedure
S = System base table
SN = Synonym
SQ = Service queue
TA = Assembly (CLR) DML trigger
TF = SQL table-valued-function
TR = SQL DML trigger
U = Table (user-defined)
UQ = UNIQUE constraint
V = View
X = Extended stored procedure
OKQ我们要得到名称的表Q用戯定义表)是cd?#8220;U”的对象;而sys.objects的类型ؓ“S”。所以,Z辑ֈ我们的最l目的,SQL语句应该是—?/p>
USE AdventureWorks SELECT name FROM sys.sysobjects WHERE type = ' U ' GO
下面我再l出一D는C#实现的代码:
]]> 两个 DataTable 删改的算?/title> http://m.shnenglu.com/colys/articles/26219.htmlcolys colys Tue, 12 Jun 2007 15:53:00 GMT http://m.shnenglu.com/colys/articles/26219.html http://m.shnenglu.com/colys/comments/26219.html http://m.shnenglu.com/colys/articles/26219.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/26219.html http://m.shnenglu.com/colys/services/trackbacks/26219.html /* 已知 DataTable (first?nbsp;second) , 两个DataTable中都有一?nbsp;ID,q且值唯一 要求:l织一个新的DataTable ,满以下: 如果 first 存在?nbsp;second 中则更新first的Name列ؓsecond的Name 如果不存在则删除该行 如果 second 的行不存在于first 添加到 first?br>*/ using System; using System.Collections; using System.Text; using System.Data; namespace ConsoleApplication1 { class Program { static void Main( string [] args) { Demo d = new Demo(); d.Run(); } } class Demo { DataTable first, second; public void Run() { int i, j; first = new DataTable(); first.Columns.Add( " ID " ); first.Columns.Add( " Name " ); DataRow dr; for (i = 1 ; i < 100 ; i ++ ) { dr = first.NewRow(); dr[ 0 ] = i; dr[ 1 ] = i; first.Rows.Add(dr); } Console.Write( " \n\nold first:\n " ); foreach (DataRow outRow in first.Rows) { Console.Write(outRow[ 0 ].ToString() + " | " + outRow[ 1 ].ToString() + " \n " ); } second = first.Clone(); this .AddToSecond( 1 , 00001 ); this .AddToSecond( 2 , 20000 ); this .AddToSecond( 5 , 55555 ); this .AddToSecond( 100 , 00100 ); this .AddToSecond( 150 , 00150 ); Console.Write( " \n\nold second:\n " ); foreach (DataRow outRow in second.Rows) { Console.Write(outRow[ 0 ].ToString() + " | " + outRow[ 1 ].ToString() + " \n " ); } int len1 = first.Rows.Count; int len2 = second.Rows.Count; ArrayList DeleteRows = new ArrayList(); ArrayList NewRows = new ArrayList(); for (i = 0 , j = 0 ; i < len1 && j < len2; ) { string se = second.Rows[j][ 0 ].ToString(); string fi = first.Rows[i][ 0 ].ToString(); int compar = se.CompareTo(fi); if (compar > 0 ) // second > first { DeleteRows.Add(i ++ ); // 已经删除?/span> } else if (compar == 0 ) { first.Rows[i][ 1 ] = second.Rows[j][ 1 ].ToString() + " (修改) " ; i ++ ; j ++ ; } else { NewRows.Add(j++ ); // 新加?/span> } } if (i < len1) { // 如果W一个没有遍历完,说明剩下的都是要删除?/span> for (; i < len1; i ++ ) { DeleteRows.Add(i); } } else if (j < len2) { // 如果W二个没有遍历完,说明剩下的都是要d?/span> for (; j < len2; j ++ ) { NewRows.Add(j); } } // delete int [] DeleteArray = ( int [])DeleteRows.ToArray( typeof ( int )); i = DeleteArray.Length - 1 ; while (i > - 1 ) { // 从后面开始删 first.Rows.RemoveAt(DeleteArray[i]); i -- ; } // add new int [] NewArray = ( int [])NewRows.ToArray( typeof ( int )); for (i = 0 ; i < NewArray.Length; i ++ ) { DataRow drNew = first.NewRow(); drNew[ 0 ] = second.Rows[NewArray[i]][ 0 ]; drNew[ 1 ] = second.Rows[NewArray[i]][ 1 ].ToString() + " (新增) " ; first.Rows.Add(drNew); } Console.Write( " \n\nresult second:\n " ); foreach (DataRow outRow in first.Rows) { Console.Write(outRow[ 0 ].ToString() + " | " + outRow[ 1 ].ToString() + " \n " ); } Console.Read(); } private void AddToSecond( object text1, object text2) { DataRow dr24 = second.NewRow(); dr24[ 0 ] = text1; dr24[ 1 ] = text2; second.Rows.Add(dr24); } } }
]]>
c#旉格式化字W串详解 http://m.shnenglu.com/colys/articles/25840.htmlcolys colys Fri, 08 Jun 2007 08:29:00 GMT http://m.shnenglu.com/colys/articles/25840.html http://m.shnenglu.com/colys/comments/25840.html http://m.shnenglu.com/colys/articles/25840.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/25840.html http://m.shnenglu.com/colys/services/trackbacks/25840.html 有时候我们要Ҏ间进行{?辑ֈ不同的显C效?br>
默认格式?2005-6-6 14:33:34
如果要换成成200506,06-2005,2005-6-6或更多的该怎么办呢
我们要用?DateTime.ToString的方?String, IFormatProvider)
using System;
using System.Globalization;
String format="D";
DateTime date=DataTime,Now;
Response.Write(date.ToString(format, DateTimeFormatInfo.InvariantInfo));
l果输出
Thursday, June 16, 2005
参数format格式详细用法
格式字符 兌属?说明
d ShortDatePattern -----08/30/2006
D LongDatePattern -----Wednesday, 30 August 2006
f 完整日期和时_长日期和短时_ -----Wednesday, 30 August 2006 23:21
F FullDateTimePatternQ长日期和长旉Q?-----Wednesday, 30 August 2006 23:22:02
g 常规Q短日期和短旉Q?-----08/30/2006 23:22
G 常规Q短日期和长旉Q?-----08/30/2006 23:23:11
m、M MonthDayPattern
r、R RFC1123Pattern
s 使用当地旉?SortableDateTimePatternQ基?ISO 8601Q?br>
t ShortTimePattern ------23:24
T LongTimePattern -------23:24:30
u UniversalSortableDateTimePattern 用于昄通用旉的格?-------2006-08-30 23:25:10Z
U 使用通用旉的完整日期和旉Q长日期和长旉Q?-----Wednesday, 30 August 2006 15:25:37
y、Y YearMonthPattern
下表列出了可被合q以构造自定义模式的模式。这些模式是区分大小写的Q例如,识别“MM”Q但不识?#8220;mm”。如果自定义模式包含I白字符或用单引hh的字W,则输出字W串也包含这些字W。未定义为格式模式的一部分或未定义为格式字W的字符按其原义复制?br>
格式模式 说明
d 月中的某一天。一位数的日期没有前导零?br>
dd 月中的某一天。一位数的日期有一个前导零?br>
ddd 周中某天的羃写名Uͼ?AbbreviatedDayNames 中定义?br>
dddd 周中某天的完整名Uͼ?DayNames 中定义?br>
M 月䆾数字。一位数的月份没有前导零?br>
MM 月䆾数字。一位数的月份有一个前导零?br>
MMM 月䆾的羃写名Uͼ?AbbreviatedMonthNames 中定义?br>
MMMM 月䆾的完整名Uͼ?MonthNames 中定义?br>
y 不包含纪元的q䆾。如果不包含U元的年份小?10Q则昄不具有前导零的年份?br>
yy 不包含纪元的q䆾。如果不包含U元的年份小?10Q则昄h前导零的q䆾?br>
yyyy 包括U元的四位数的年份?br>
gg 时期或纪元。如果要讄格式的日期不h兌的时期或U元字符Ԍ则忽略该模式?br>
h 12 时制的时。一位数的小时数没有前导零?br>
hh 12 时制的时。一位数的小时数有前导零?br>
H 24 时制的时。一位数的小时数没有前导零?br>
HH 24 时制的时。一位数的小时数有前导零?br>
m 分钟。一位数的分钟数没有前导零?br>
mm 分钟。一位数的分钟数有一个前导零?br>
s U。一位数的秒数没有前导零?br>
ss U。一位数的秒数有一个前导零?br>
f U的数_ֺZ位。其余数字被截断?br>
ff U的数_ֺZ位。其余数字被截断?br>
fff U的数_ֺZ位。其余数字被截断?br>
ffff U的数_ֺ为四位。其余数字被截断?br>
fffff U的数_ֺZ位。其余数字被截断?br>
ffffff U的数_ֺ为六位。其余数字被截断?br>
fffffff U的数_ֺZ位。其余数字被截断?br>
t ?AMDesignator ?PMDesignator 中定义的 AM/PM 指示的W一个字W(如果存在Q?br>
tt ?AMDesignator ?PMDesignator 中定义的 AM/PM 指示(如果存在Q?br>
z 时区偏移量(“+”?#8220;-”后面仅跟时Q。一位数的小时数没有前导零。例如,太^z标准时间是“-8”?br>
zz 时区偏移量(“+”?#8220;-”后面仅跟时Q。一位数的小时数有前导零。例如,太^z标准时间是“-08”?br>
zzz 完整时区偏移量(“+”?#8220;-”后面跟有时和分钟)。一位数的小时数和分钟数有前导零。例如,太^z标准时间是“-08:00”?br>
: ?TimeSeparator 中定义的默认旉分隔W?br>
/ ?DateSeparator 中定义的默认日期分隔W?br>
% c 其中 c 是格式模式(如果单独使用Q。如果格式模式与原义字符或其他格式模式合qӞ则可以省?#8220;%”字符?br>
\ c 其中 c 是Q意字W。照原义昄字符。若要显C反斜杠字符Q请使用“\\”?br>
只有上面W二个表中列出的格式模式才能用于创徏自定义模式;在第一个表中列出的标准格式字符不能用于创徏自定义模式。自定义模式的长度至ؓ两个字符Q例如,
DateTime.ToString( "d") q回 DateTime |“d”是标准短日期模式?br>
DateTime.ToString( "%d") q回月中的某天;“%d”是自定义模式?br>
DateTime.ToString( "d ") q回后面跟有一个空白字W的月中的某天;“d”是自定义模式?br>
比较方便的是,上面的参数可以随意组?q且不会出错,多试?肯定会找C要的旉格式
如要得到2005q?6?q样格式的时?br>
可以q样?
date.ToString("yyyyqMM?, DateTimeFormatInfo.InvariantInfo)
如此cL
date.ToString("yyyy/MM/dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo) ]]> c#操作excel后关闭excel.exe的方? http://m.shnenglu.com/colys/articles/25265.htmlcolys colys Fri, 01 Jun 2007 03:51:00 GMT http://m.shnenglu.com/colys/articles/25265.html http://m.shnenglu.com/colys/comments/25265.html http://m.shnenglu.com/colys/articles/25265.html#Feedback 6 http://m.shnenglu.com/colys/comments/commentRss/25265.html http://m.shnenglu.com/colys/services/trackbacks/25265.html C#和Asp.net下excelq程一被打开,有时无法关? 其是website.对关闭该q程有过GC、release{方法,但这些方法ƈ不是在所有情况下均适用?nbsp; 于是提出了kill process的方? 目前我见q的Ҏ多是用进E创建时间筛选excel.exeq程, 然后kill ?nbsp; q样的方法是不精的, 也是不安全的, 通过对网上一些关于Apiq用文章的阅? 我找C更ؓ直接_扑ֈq个processqkill的方法,以下是代码 using System.Runtime.InteropServices; [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); protected void Button1_Click(object sender, EventArgs e) { Excel.ApplicationClass excel = new Microsoft.Office.Interop.Excel.ApplicationClass(); excel.Workbooks.Open("d:\aaa.xls", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); IntPtr t = new IntPtr(excel.Hwnd); int k = 0; GetWindowThreadProcessId(t, out k); System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); p.Kill(); }
以上代码癑ֈ百成功的关闭excel.exeq程 我的做法是结合两者,先释放资源,然后关闭q程?br>同时|上说避免用GC.Collect Ҏ (),因ؓ会导致整个clrq行gcQ媄响你的性能.所以我也没有调用GC.Collect
]]>q制介绍 http://m.shnenglu.com/colys/articles/22816.htmlcolys colys Wed, 25 Apr 2007 11:35:00 GMT http://m.shnenglu.com/colys/articles/22816.html http://m.shnenglu.com/colys/comments/22816.html http://m.shnenglu.com/colys/articles/22816.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/22816.html http://m.shnenglu.com/colys/services/trackbacks/22816.html
1 . 十进制数 十进制数的两个主要特点: ⑴有十个不同的数字: 0 ?/span>1 ?/span>2 ?/span>3 ?/span>4 ?/span>5 ?/span>6 ?/span>7 ?/span>8 ?/span>9 ; ⑵逢十q一的进位法,10是十q制数的基数(q制中所用不同数字的个数)?br> ( 1993 ) 10 = 1 × 103 + 9 × 102 + 9 × 101 + 3 × 100 (每位上的pL只在0?中取? 2 . 二进制数 二进制数的两个主要特点: ⑴有两个不同的数字: 0 ?/span>1 ; ⑵逢二q一的进位法,2是二q制数的基数?br> ( 1011 ) 2 = 1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 (每位上的pL只在0?中取? 3 . 八进制数 八进制数的两个主要特点: ⑴采用八个不同的数字Q?/span>0 ?/span>1 ?/span>2 ?/span>3 ?/span>4 ?/span>5 ?/span>6 ?/span>7 ; ⑵逢八q一的进位法,8是八q制数的基数?br> ( 1725 ) 8 = 1 × 83 + 7 × 82 + 2 × 81 + 5 × 80 (每位上的pL只在0?中取? 4 . 十六q制 十六q制数的两个主要特点Q?br> ⑴有十六个不同的数字Q?/span>0 ?/span>1 ?/span>2 ?/span>3 ?/span>4 ?/span>5 ?/span>6 ?/span>7 ?/span>8 ?/span>9 、A、B、C、D、E、F(其中后六个数字符号其值对应于十进制的10, 11 , 12 , 13 , 14 , 15 Q也有选用S,T,U,V,W,X的记?; ⑵逢十六进一的进位法,16是十六进制数的基数?br> (B56E) 16 = B× 163 + 5 × 162 + 6 × 161 + E× 160 = 11 × 163 + 5 × 162 + 6 × 161 + 14 × 160 二进制换ؓ十六q制是这?
先把二进制从低位Q也是从右到左Q按四位一l分开Q分到最后不够四位的也按一l来?/span>分好以后再把每组的二q制换算成十六进Ӟ之后再接换算好的l合h可以了?br> 如: 1101110111010 分组后是: 1Q?011Q?011Q?010 每组换算成十六进制是1QB,B,A l合?BBA
]]>Asp.net2.0水晶报表的一些示例源?/title> http://m.shnenglu.com/colys/articles/22554.htmlcolys colys Sat, 21 Apr 2007 07:11:00 GMT http://m.shnenglu.com/colys/articles/22554.html http://m.shnenglu.com/colys/comments/22554.html http://m.shnenglu.com/colys/articles/22554.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/22554.html http://m.shnenglu.com/colys/services/trackbacks/22554.html 最q关注了一下Asp.net2.0中水晶报表的资料Q发现示例少之又(怀疑是水晶报表免费的比较少的缘故)Q搜集到了Asp.net官方的许多示例源码,试了几个q不错,q里发给大家分n一下(我仅把Asp.net C#部分提出来了Q?br> 环境VS2005+ACCESS
q些例子实现了水晶报表的查看、柱状图昄、打印、导出、羃攄基本功能Q如果想了解更多比如说利用DataSet方式、Push、Pull{模式需要自己更׃步的研究?
׃其中源码太多Q?1aspx仅仅q行了部分调,一些配|文件请自行更改
代码打包下蝲
]]>
Asp.net无刷C文验证码调试成功Q特分nl大?/title> http://m.shnenglu.com/colys/articles/22555.htmlcolys colys Sat, 21 Apr 2007 03:22:00 GMT http://m.shnenglu.com/colys/articles/22555.html http://m.shnenglu.com/colys/comments/22555.html http://m.shnenglu.com/colys/articles/22555.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/22555.html http://m.shnenglu.com/colys/services/trackbacks/22555.html 以前在网上找C很多关于中文验证码的文章Q园子里也有Q大家自己去扑Q,但是都没有调成功,d?br>The target '__Page' for the callback could not be found or did not implement ICallbackEventHandler不能ICallbackEventHandler回掉的错误,我进行了一下修正ƈ整理Q现在可以实C中文验证码无h的操作,现特把全部源码分享给大家 核心源码
1 public partial class Image : System.Web.UI.Page 2 { 3 protected void Page_Load( object sender, EventArgs e) 4 { 5 CreateCheckCodeImage(GenCode(4 )); 6 } 7 /**/ /**/ /**/ /// <summary> 8 /// '产生随机字符?br> 9 /// </summary> 10 /// <param name="num"> 随机出几个字W?/span></param> 11 /// <returns> 随机出的字符?/span></returns> 12 private string GenCode( int num) 13 { 14 string str = " 的一是在不了有和中大Z个国我以要他时来用们... " ; 15 char [] chastr = str.ToCharArray(); 16 17 string code = "" ; 18 Random rd = new Random(); 19 int i; 20 for (i = 0 ; i < num; i ++ ) 21 { 22 // code += source[rd.Next(0, source.Length)]; 23 code += str.Substring(rd.Next( 0 , str.Length), 1 ); 24 }25 return code; 26 27 }28 29 /**/ /**/ /**/ /// <summary> 30 /// 生成囄Q增加背景噪音线、前景噪音点Q?br> 31 /// </summary> 32 /// <param name="checkCode"> 随机出字W串 </param> 33 private void CreateCheckCodeImage( string checkCode) 34 { 35 if (checkCode.Trim() == "" || checkCode == null ) 36 return ; 37 Session[" Code " ] = checkCode; // 字W串保存到Session中,以便需要时q行验证 38 System.Drawing.Bitmap image = new System.Drawing.Bitmap(( int )(checkCode.Length * 21.5 ), 22 ); 39 Graphics g = Graphics.FromImage(image); 40 try 41 { 42 // 生成随机生成?/span>43 Random random = new Random(); 44 45 // 清空囄背景?/span>46 g.Clear(Color.White); 47 48 // d片的背景噪音U?/span>49 int i; 50 for (i = 0 ; i < 25 ; i ++ ) 51 { 52 int x1 = random.Next(image.Width); 53 int x2 = random.Next(image.Width); 54 int y1 = random.Next(image.Height); 55 int y2 = random.Next(image.Height); 56 g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); 57 }58 59 Font font = new System.Drawing.Font( " Arial " , 12 , (System.Drawing.FontStyle.Bold)); 60 System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush( new Rectangle( 0 , 0 , image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F , true ); 61 g.DrawString(checkCode, font, brush, 2 , 2 ); 62 63 // d片的前景噪音?/span>64 g.DrawRectangle( new Pen(Color.Silver), 0 , 0 , image.Width - 1 , image.Height - 1 ); 65 System.IO.MemoryStream ms = new System.IO.MemoryStream(); 66 image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);67 Response.ClearContent();68 Response.ContentType = " image/Gif " ; 69 Response.BinaryWrite(ms.ToArray());70 71 } 72 catch 73 { 74 g.Dispose();75 image.Dispose();76 }77 78 }
希望该源码只是一个抛砖引玉的作用Q你可以q行修改Q比如说改中文字库,字体背景噪音{等 默认帐号密码均ؓ51aspxQ这里用L录只是一个验证的例子Q没有其他功?/p>
作?1aspx 完整源码下蝲地址http://www.51aspx.com/CV/ZhongWenYanZhengMa
]]> 多文件上传示例源?默认支持各种cdQ包括图? http://m.shnenglu.com/colys/articles/22558.htmlcolys colys Tue, 10 Apr 2007 03:45:00 GMT http://m.shnenglu.com/colys/articles/22558.html http://m.shnenglu.com/colys/comments/22558.html http://m.shnenglu.com/colys/articles/22558.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/22558.html http://m.shnenglu.com/colys/services/trackbacks/22558.html 前几天在园子里发布了一?font color=#646464>囄上传(加水印、羃略图、远E保存)的简单例?/font> Q很受大家的Ƣ迎Q这cd发布一?a title=下蝲该源? target=_blank>多文件上传示例源?默认支持各种cdQ包括图?的例子,可以同时扚w上传文gQ包括图片) |上包括园子里有很多多文件上传的例子Q但是没有完整的CZ代码Q本人整理了一下发布出来,q样更直观,希望对大家有所帮助 开发环境VS2005下蝲该源?/a> 部分源码
public partial class _Default : System.Web.UI.Page { static public ArrayList hif = new ArrayList(); // 保存文g列表 public int filesUploaded = 0 ; // 上传文g的数?/span> protected void Page_Load( object sender, EventArgs e) { } /**/ /// <summary> /// 要上传的文件添加到listbox?br> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void AddFile_Click( object sender, EventArgs e) { if (Page.IsPostBack == true ) { hif.Add(FindFile); FileList.Items.Add(FindFile.PostedFile.FileName); } else { } } /**/ /// <summary> /// 从listbox中删除指定的文g /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void RemvFile_Click( object sender, EventArgs e) { if (FileList.SelectedIndex == - 1 ) { TipInfo.Text = " 错误 - 必须指定要删除的文g. " ; return ; } else if (FileList.Items.Count != 0 ) { hif.RemoveAt(FileList.SelectedIndex); FileList.Items.Remove(FileList.SelectedItem.Text); TipInfo.Text = "" ; } } /**/ /// <summary> /// 循环上传listbox中的文g到指定的文g夹下 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void Upload_ServerClick( object sender, System.EventArgs e) { string baseLocation = Server.MapPath( " UploadFiles/ " ); // 上传路径 string status = "" ; // 上传成功后显C的文g列表 if ((FileList.Items.Count == 0 ) && (filesUploaded == 0 )) { TipInfo.Text = " 错误 - 必须指定要上传的文g. " ; return ; } else { foreach (System.Web.UI.HtmlControls.HtmlInputFile HIF in hif) { try { string fn = System.IO.Path.GetFileName(HIF.PostedFile.FileName); HIF.PostedFile.SaveAs(baseLocation + fn); filesUploaded ++ ; status += fn + " <br> " ; } catch (Exception err) { TipInfo.Text = " 上传错误 " + baseLocation + " <br> " + err.ToString(); } } if (filesUploaded == hif.Count) { TipInfo.Text = " ׃传了 " + filesUploaded + " 个文件?nbsp;<br> " + status; } hif.Clear(); FileList.Items.Clear(); } } }
]]> JavaScript与C# Windows应用E序交互 http://m.shnenglu.com/colys/articles/20058.htmlcolys colys Sun, 18 Mar 2007 06:06:00 GMT http://m.shnenglu.com/colys/articles/20058.html http://m.shnenglu.com/colys/comments/20058.html http://m.shnenglu.com/colys/articles/20058.html#Feedback 0 http://m.shnenglu.com/colys/comments/commentRss/20058.html http://m.shnenglu.com/colys/services/trackbacks/20058.html 1 < html > 2 < head > 3 < meta http - equiv = " Content-Language " content = " zh-cn " > 4 < script language = " javascript " type = " text/javascript " > 5 < ! -- 提供lC#E序调用的方法?/span>--> 6 function messageBox(message) 7 { 8 alert(message); 9 } 10 </ script > 11 </ head > 12 13 < body > 14 < ! -- 调用C#Ҏ --> 15 < button onclick = " window.external.MyMessageBox('javascript讉KC#代码') " > 16 javascript讉KC#代码 </ button > 17 </ body > 18 </ html >
二?/span> 建立 Windows 应用E序
1. 创徏 Windows 应用E序目
2. ?/span>Form1 H体中添?/span>WebBrowser 控g
3. ?/span>Form1 cȝ上方d
[System.Runtime.InteropServices.ComVisibleAttribute (true )]
q是Z该c设|ؓcom 可访问。如果不q行该声明将会出错。出错信息如下图所C:
如:
[System.Runtime.InteropServices.ComVisibleAttribute (true )]
public partial class Form1 : Form
4 Q初始化WebBrowser ?span>Url ?span>ObjectForScripting两个属性?/span>
Url 属性:WebBrowser 控g昄的网\?/span>
ObjectForScripting 属性:该对象可由显C在WebBrowser 控g中的|页所包含的脚本代码访问?/span>
?span>Url 属性设|ؓ需要进行操作的늚URL 路径?/span>
JavaScript 通过 window.external 调用 C# 公开的方法。即?/span>ObjectForScripting 属性设|的cȝ实例中所包含的公共方法。具体设|例子如下:
System.IO.FileInfo file = new System.IO.FileInfo ("index.htm" );
// WebBrowser 控g昄的网\?/span>
webBrowser1.Url = new Uri (file.FullName);
// 当前类讄为可p本访?/span>
webBrowser1.ObjectForScripting = this ;
5 Q?span>C# 调用JavaScript Ҏ
通过WebBrowser cȝDocument 属性中?span>InvokeScript Ҏ调用当前|页?span>JavascriptҎ。如Q?/span>
// 调用JavaScript ?span>messageBox ҎQƈ传入参数
object [] objects = new object [1];
objects[0] = "C# 讉KJavaScript 脚本" ;
webBrowser1.Document.InvokeScript("messageBox" , objects);
完整代码如下Q?/span>
1 [System.Runtime.InteropServices.ComVisibleAttribute( true )] 2 3 public partial class Form1 : Form 4 5 { 6 7 public Form1() 8 9 { 10 11 InitializeComponent(); 12 13 System.IO.FileInfo file = new System.IO.FileInfo( " index.htm " ); 14 15 // WebBrowser控g昄的网\?/span>16 17 webBrowser1.Url = new Uri(file.FullName); 18 19 // 当前类讄为可p本访?/span>20 21 webBrowser1.ObjectForScripting = this ; 22 23 } 24 25 26 27 private void button1_Click( object sender, EventArgs e) 28 29 { 30 31 // 调用JavaScript的messageBoxҎQƈ传入参数 32 33 object [] objects = new object [ 1 ]; 34 35 objects[ 0 ] = " C#讉KJavaScript脚本 " ; 36 37 webBrowser1.Document.InvokeScript( " messageBox " , objects); 38 39 } 40 41 // 提供lJavaScript调用的方?/span>42 43 public void MyMessageBox( string message) 44 45 { 46 47 MessageBox.Show(message); 48 } 49 } 50
]]>
þþwww˳ɾƷ |
AVþþƷݺݰ˳
|
91鶹Ʒ91þþ |
97Ʒ˾þþô߽97 |
þþƷ99þ |
99reþùƷҳ |
þþþù˾Ʒҹ |
˳˳ۺþþ |
72ŷþþþôƽ |
þþƷ99Ӱ |
69Ʒþþþùۿ |
Ʒþۺ |
ѾþþƷ99reѾy |
ƷƷھþø |
պһþ99 |
ձþþþĻ |
Ļþ2020 |
7777þĻ |
97㽶þҹɫƷ |
Ʒþþþþþö |
seguiþùƷ |
ԭ1769þѲ
|
Ʒ9999þþþ |
þþۺϾɫۺϾ |
91ƷùۺϾþ |
ԭƷ99þþƷ66 |
Ůþþþþ |
˾ƷŮ˾þþ
|
ɫۺϾþĻۺ |
þĻȫ |
þþƷƷ2020 |
һþaþþƷۺ㽶 |
avƬþ |
þùƷҰAV |
ٸþþþþ4 |
99þ99ֻѵľƷ |
˾þۺϳ |
Ʒרþþ |
ҹþþþüŮӰԺ |
þþ뾫Ʒպý |
Ⱦþԭɫwww |