<?xml version="1.0" encoding="GBK"?>
<?xml-stylesheet href="/style/rss.css" type="text/css"?>
<rss version="2.0" xmlns:eb="http://blog.tom.com/">
<channel>
  <title>感悟收获</title>
  <link>http://blog.tom.com/kaijie_luo</link>
  <description><![CDATA[我的心情，我的记忆，我的梦想，我的感悟。 ]]></description>
  <language>zh</language>
  <generator>newblog.tom.com RSS</generator>
  <pubDate></pubDate>    <item>
		<title><![CDATA[ VB.NET编程之托盘程序篇 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4180.html</link>
		<description><![CDATA[ <p style="TEXT-INDENT: 2em">托盘程序是指这样一类程序：当程序运行后，会在系统的托盘区（也有说是状态区域）创建此程序的图标，使用者可以通过点击图标出现的菜单来控制程序的运行状态。托盘程序有很多优点，如不占屏幕，后台运行，便于控制等。所以现在越来越多的程序都做成了托盘程序。在VB.NET中，编写托盘程序是比较方便和简单的。这是因为VB.NET没有自身类库，它所使用的类库是.Net框架中为所有.Net平台开发语言提供的公用类库——.Net FrameWork SDK。在这个类库中，为编写托盘程序提供了具体的类，调用这些类就可以实现程序的托盘效果了。从而也就摆脱了它的前身VB在处理这类问题时候的烦琐。下面就通过二个具体例子来了解并掌握如何用VB.NET编写托盘程序。</p>
<p style="TEXT-INDENT: 2em"><strong>本文程序的设计及运行环境</strong></p>
<p style="TEXT-INDENT: 2em">（1）Windows 2000 Service</p>
<p style="TEXT-INDENT: 2em">（2）Net Framework SDK 正式版</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center><font color="#000099"><strong>静态托盘程序的编写过程</strong></font></center>
<p style="TEXT-INDENT: 2em">所谓静态托盘程序是指程序运行后，在系统托盘区的图标处于静止状态的托盘程序。动态托盘程序正好与之相反，它是指在系统托盘区图标呈现动画效果的一类托盘程序。下面就来探讨一下VB.NET是如何实现静态托盘程序。</p>
<p style="TEXT-INDENT: 2em">.Net FrameWork SDK为编写托盘程序提供了一个组件：NotifyIcon组件。NotifyIcon组件是一个WinForm组件，位于命名空间"System.Windows.Forms"中，在VB.NET程序中，只要创建一个NotifyIcon组件的实例，并且对NotifyIcon实例的"Icon"属性赋值，这样一个简单的托盘程序就完成了。下面就是这个简单托盘程序对于的代码（Form1.vb）：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Public Class Form1 Inherits System.Windows.Forms.Form #Region " Windows 窗体设计器生成的代码 " Public Sub New ( ) MyBase.New ( ) '该调用是 Windows 窗体设计器所必需的。 InitializeComponent ( ) '在 InitializeComponent ( ) 调用之后添加任何初始化 End Sub '窗体重写处置以清理组件列表。 Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean ) If disposing Then If Not ( components Is Nothing ) Then components.Dispose ( ) End If End If MyBase.Dispose ( disposing ) End Sub 'Windows 窗体设计器所必需的 Private components As System.ComponentModel.IContainer '注意：以下过程是 Windows 窗体设计器所必需的 '可以使用 Windows 窗体设计器修改此过程。 '不要使用代码编辑器修改它。 Friend WithEvents NotifyIcon1 As System.Windows.Forms.NotifyIcon '创建一个NotifyIcon实例 Friend TrayIcon = New Icon ( "Tray.ico" ) '创建一个Icon实例 &lt;System.Diagnostics.DebuggerStepThrough ( ) &gt; Private Sub InitializeComponent ( ) Me.components = New System.ComponentModel.Container ( ) Me.NotifyIcon1 = New System.Windows.Forms.NotifyIcon ( Me.components ) Me.NotifyIcon1.Text = "NotifyIcon1" Me.NotifyIcon1.Visible = True '对NotifyIcon实例的Icon属性赋值，完成简单托盘程序 Me.NotifyIcon1.Icon = TrayIcon Me.AutoScaleBaseSize = New System.Drawing.Size ( 6 , 14 ) Me.ClientSize = New System.Drawing.Size ( 292 , 273 ) Me.Name = "Form1" Me.Text = "Form1" End Sub #End Region End Class '启动程序 Module Module1 Sub Main ( ) Application.Run ( new Form1 ( ) ) End sub End Module</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="TEXT-INDENT: 2em">但是这个托盘程序还不是真正意义上的托盘程序，因为它还有很多具体功能没有实现，下面就列出这些功能，并介绍具体的实现方法</p>
<p style="TEXT-INDENT: 2em">（1）.托盘程序是隐藏窗口后，程序不应该显示在任务栏中，并且一般运行后都不显示窗口：</p>
<p style="TEXT-INDENT: 2em">这是通过设定窗体的属性来完成的，具体如下：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">'设定程序不应该显示在任务栏 Me.ShowInTaskbar = False '设定程序运行后最小化 Me.WindowState = System.Windows.Forms.FormWindowState.Minimized</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="TEXT-INDENT: 2em">（2）.定义托盘程序中的菜单和相关事件：</p>
<p style="TEXT-INDENT: 2em">往NotifyIcon实例中添加菜单，首先要创建ContextMenu实例，此实例主要作用是表示快捷菜单，其中的菜单项是通过创建MenuItem实例来实现，托盘程序中的菜单有几个菜单项，就创建几个MenuItem实例。然后把这些菜单项加入到ContextMenu实例，并把此实例赋值给NotifyIcon实例的ContextMenu属性，这样托盘程序右键点击弹出的菜单就完成了。下面是具体代码：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">创建ContextMenu实例和MenuItem实例： Friend WithEvents ContextMenu1 As System.Windows.Forms.ContextMenu Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem3 As System.Windows.Forms.MenuItem</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="TEXT-INDENT: 2em">把这些菜单项加入到ContextMenu实例，并把ContextMenu实例赋值给NotifyIcon实例的ContextMenu属性：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Me.MenuItem1 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem2 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem3 = New System.Windows.Forms.MenuItem ( ) Me.NotifyIcon1.ContextMenu = Me.ContextMenu1 Me.NotifyIcon1.Text = "VB.NET的托盘程序" Me.NotifyIcon1.Visible = True '设定托盘程序托盘区位置显示图标 Me.NotifyIcon1.Icon = TrayIcon '在ContextMenu实例中加入菜单项 Me.ContextMenu1.MenuItems.Add ( Me.MenuItem1 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem2 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem3 ) Me.MenuItem1.Index = 0 Me.MenuItem1.Text = "显示窗体" Me.MenuItem2.Index = 1 Me.MenuItem2.Text = "隐藏窗体" Me.MenuItem3.Index = 2 Me.MenuItem3.Text = "退出"</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="TEXT-INDENT: 2em">当把ContextMenu实例赋值给NotifyIcon实例的ContextMenu属性后，托盘程序的缺省状态是当鼠标右击托盘图标，就会弹出对应的菜单。这时就可以对其中的每一个菜单项定义相应的事件以及具体的处理方法。一个完整的静态托盘程序的编写过程就完成了。</p>
<p style="TEXT-INDENT: 2em">最后要请读者注意的是，由于本文中的托盘程序的图标并不是通过创建资源文件来实现的，而是通过创建Icon实例完成的。所以在程序运行的时候，必须在程序的当前目录存在一个图标文件，并且此图标文件的名称为"Tray.ico"。下面是这个静态托盘程序的完整的代码清单（Form2.vb）：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Public Class Form1 Inherits System.Windows.Forms.Form #Region " Windows 窗体设计器生成的代码 " Public Sub New ( ) MyBase.New ( ) '该调用是 Windows 窗体设计器所必需的。 InitializeComponent ( ) '在 InitializeComponent ( ) 调用之后添加任何初始化 End Sub '窗体重写处置以清理组件列表。 Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean ) If disposing Then If Not ( components Is Nothing ) Then components.Dispose ( ) End If End If MyBase.Dispose ( disposing ) End Sub 'Windows 窗体设计器所必需的 Private components As System.ComponentModel.IContainer '注意：以下过程是 Windows 窗体设计器所必需的 '可以使用 Windows 窗体设计器修改此过程。 '不要使用代码编辑器修改它。 Friend WithEvents NotifyIcon1 As System.Windows.Forms.NotifyIcon Friend WithEvents ContextMenu1 As System.Windows.Forms.ContextMenu Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem3 As System.Windows.Forms.MenuItem Friend TrayIcon = New Icon ( "Tray.ico" ) &lt;System.Diagnostics.DebuggerStepThrough ( ) &gt; Private Sub InitializeComponent ( ) Me.components = New System.ComponentModel.Container ( ) Me.NotifyIcon1 = New System.Windows.Forms.NotifyIcon ( Me.components ) Me.ContextMenu1 = New System.Windows.Forms.ContextMenu ( ) Me.MenuItem1 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem2 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem3 = New System.Windows.Forms.MenuItem ( ) Me.NotifyIcon1.ContextMenu = Me.ContextMenu1 Me.NotifyIcon1.Text = "VB.NET的托盘程序" Me.NotifyIcon1.Visible = True '设定托盘程序托盘区位置显示图标 Me.NotifyIcon1.Icon = TrayIcon '在ContextMenu实例中加入菜单项 Me.ContextMenu1.MenuItems.Add ( Me.MenuItem1 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem2 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem3 ) Me.MenuItem1.Index = 0 Me.MenuItem1.Text = "显示窗体" Me.MenuItem2.Index = 1 Me.MenuItem2.Text = "隐藏窗体" Me.MenuItem3.Index = 2 Me.MenuItem3.Text = "退出" Me.AutoScaleBaseSize = New System.Drawing.Size ( 6 , 14 ) Me.ClientSize = New System.Drawing.Size ( 292 , 273 ) Me.Name = "Form1" '设定程序不应该显示在任务栏 Me.ShowInTaskbar = False Me.Text = "VB.NET之WinForm编程托盘程序篇" '设定程序运行后最小化 Me.WindowState = System.Windows.Forms.FormWindowState.Minimized End Sub #End Region '显示托盘程序窗口 Private Sub MenuItem1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles MenuItem1.Click Me.WindowState = FormWindowState.Normal Me.Show ( ) End Sub '隐藏托盘程序窗口 Private Sub MenuItem2_Click ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles MenuItem2.Click Me.Hide ( ) End Sub '推出托盘程序窗口 Private Sub MenuItem3_Click ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles MenuItem3.Click NotifyIcon1.Dispose ( ) Application.Exit ( ) End Sub '双击图标显示窗体 Private Sub NotifyIcon1_DoubleClick ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles NotifyIcon1.DoubleClick Me.WindowState = FormWindowState.Normal Me.Show ( ) End Sub End Class '启动程序 Module Module1 Sub Main ( ) Application.Run ( new Form1 ( ) ) End sub End Module</td>
</tr>
</tbody>
</table>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em">Form2.vb经过了下列命令编译、连接后：</p>
<p style="TEXT-INDENT: 2em">Vbc /r:system.dll /r:system.windows.froms.dll /r:system.drawing.dll form2.vb</p>
<p style="TEXT-INDENT: 2em">就可以得到Form2.exe，下图是From2.exe运行的界面：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/washingto/20070828a5.jpg"></center>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center>图01：托盘程序运行界面01</center>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center><font color="#000099"><strong>动态托盘程序的编写过程</strong></font></center>
<p style="TEXT-INDENT: 2em">动态托盘程序中的托盘图标之所以能够呈现动画效果，是因为程序中的一个定时器组</p>
<p style="TEXT-INDENT: 2em">件每隔一段时间都不断切换托盘图标。本文是通过二个图标的切换来表现动态效果的，读者如果有好的、连续的图标，也可以设定多个图标的切换，而这只需要修改Timer1定时器中的"Tick"事件中的代码就可以了。下面是此动态托盘程序的具体编制步骤：</p>
<p style="TEXT-INDENT: 2em"><strong>要创建程序中的实例和变量：</strong></p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Friend WithEvents NotifyIcon1 As System.Windows.Forms.NotifyIcon Friend WithEvents ContextMenu1 As System.Windows.Forms.ContextMenu Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem Friend WithEvents MenuItem3 As System.Windows.Forms.MenuItem '创建Icon实例，用以切换图标 Friend Icon1 = New Icon ( "icon1.ico" ) Friend Icon2 = New Icon ( "icon2.ico" ) '为不同图标的切换提供标识符 Dim BeginFlag As Boolean = True '定时器 Friend WithEvents Timer1 As System.Windows.Forms.Timer</td>
</tr>
</tbody>
</table>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"><strong>初始化实例：</strong></p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Me.components = New System.ComponentModel.Container ( ) Me.NotifyIcon1 = New System.Windows.Forms.NotifyIcon ( Me.components ) Me.ContextMenu1 = New System.Windows.Forms.ContextMenu ( ) Me.MenuItem1 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem2 = New System.Windows.Forms.MenuItem ( ) Me.MenuItem3 = New System.Windows.Forms.MenuItem ( ) Me.Timer1 = New System.Windows.Forms.Timer ( Me.components ) Me.NotifyIcon1.ContextMenu = Me.ContextMenu1 Me.NotifyIcon1.Text = "VB.NET的托盘程序" Me.NotifyIcon1.Visible = True '设定托盘程序托盘区位置显示缺省图标 Me.NotifyIcon1.Icon = Icon1 '在ContextMenu实例中加入菜单项 Me.ContextMenu1.MenuItems.Add ( Me.MenuItem1 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem2 ) Me.ContextMenu1.MenuItems.Add ( Me.MenuItem3 ) Me.MenuItem1.Index = 0 Me.MenuItem1.Text = "开始转动" Me.MenuItem2.Index = 1 Me.MenuItem2.Text = "停止转动" Me.MenuItem3.Index = 2 Me.MenuItem3.Text = "退出" Me.AutoScaleBaseSize = New System.Drawing.Size ( 6 , 14 ) Me.ClientSize = New System.Drawing.Size ( 292 , 273 ) Me.Name = "Form1" Me.ShowInTaskbar = False Me.Text = "VB.NET之WinForm编程动态托盘程序" Me.WindowState = System.Windows.Forms.FormWindowState.Minimized</td>
</tr>
</tbody>
</table>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"><strong>定义托盘程序中菜单项对应的事件，以及具体的处理方法：</strong></p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">'开始托盘图标的转动 Private Sub MenuItem1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles MenuItem1.Click Timer1.Enabled = True End Sub '停止托盘图标的转动 Private Sub MenuItem2_Click ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles MenuItem2.Click Timer1.Enabled = False End Sub '关闭程序，清除托盘资源 Private Sub MenuItem3_Click ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles MenuItem3.Click NotifyIcon1.Dispose ( ) Application.Exit ( ) End Sub '根据标识符，来确定托盘图标类型 Private Sub Timer1_Tick ( ByVal sender As Object , ByVal e As System.EventArgs ) Handles Timer1.Tick If BeginFlag = True Then NotifyIcon1.Icon = Icon2 BeginFlag = False Else NotifyIcon1.Icon = Icon1 BeginFlag = True End If End Sub</td>
</tr>
</tbody>
</table>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em">至此编写动态托盘程序的主要步骤就介绍完了，和上面的静态托盘程序相同，在运行此程序的时候必须保证此程序当前目录存在二个Icon文件，并且名称为"Icon1.ico"和"Icon2.ico"。这里并没有给出动态托盘程序的完整代码清单，读者只需要把上面这些关键步骤的代码覆盖到Form2.vb中的相应位置就可以得到动态托盘程序的源程序文件Form3.vb。这应该不算很难，下面是编译Form3.vb的命令：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em"></p>
<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
<tbody>
<tr>
<td bgcolor="#E6E6E6">Vbc /r:system.dll /r:system.windows.froms.dll /r:system.drawing.dll form2.vb</td>
</tr>
</tbody>
</table>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<p style="TEXT-INDENT: 2em">成功编译、连接后就得到Form3.exe，下图是Form3.exe的运行界面：</p>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/washingto/20070828a6.jpg"></center>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center>图02：托盘程序运行界面02</center>
<p style="TEXT-INDENT: 2em">&nbsp;</p>
<center><font color="#000099"><strong>总结</strong></font></center>
<p style="TEXT-INDENT: 2em">托盘程序是现在比较流行的一种程序类型。本文中介绍的二个程序，也是托盘程序中比较典型的二个，希望对各位了解并掌握编写托盘程序有所帮助。</p> ]]></description>
		<eb:creationDate>2009-05-15 13:22:23</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ VB.NET连接数据库总结 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4176.html</link>
		<description><![CDATA[ <p>一、先介绍ADO.NET和ODBC.NET<br>
<br>
ADO .NET由Microsoft ActiveX Data Objects (ADO)改进而来，它提供平台互用和可收缩的数据访问功能，是Visual Basic.NET进行数据库编程所使用的重要工具。ADO.NET 使用了某些 ADO 的对象，如 Connection 和 Command 对象，并且还引入了新的对象。主要的新 ADO.NET 对象包括 DataSet、DataReader 和 DataAdapter。<br>
<br>
ODBC.NET是.NET框架中另外一个很有用的用于数据库开发的类库。但是，在.NET FrameWork SDK1.0版中不包含ODBC.NET，要使用ODBC.NET请到微软网站下载，具体下载地址：http://msdn.microsoft.com/library/default.asp?url=/downloads/list/netdevframework.asp（文件名是odbc_net.msi）在默认情况下，安装路径是“C:\Program File\Microsoft.net\odbc.net”。安装后的组件名为Microsoft.Data.Odbc.dll文件。<br>
<br>
添加ODBC .NET Data Provider的步骤：<br>
<br>
启动Visual Basic.NET开发环境，选中菜单栏的[工具]—&gt;[数据]—&gt;[自定义工具箱]，在弹出的[自定义工具箱]对话框中选[.Net 框架组件]单击[浏览]按钮，在“C:\Program File\Microsoft.net\odbc.net”目录下选择Microsoft.Data.Odbc.dll文件。接下来就在[自定义工具箱]中选择“OdbcCommand”、“OdbcCommandBuilder”、“OdbcConnection”、“OdbcDataApdater”后，单击[确定]。至此，完成了在Visual Basic.NET中加入ODBC .NET。<br>
<br>
二、接下来介绍数据提供者（Data Provider）<br>
<br>
ADO.NET和ODBC.NET两者共提供了三种数据提供者，其中ADO.NET提供两种（The SQL Server .NET Data Provider和 The OLE DB .NET Data Provider ）ODBC .NET提供一种（The ODBC .NET Data Provider）。表1是三种数据提供者及其支持的数据库:<br>
<br>
数据提供者（Data Provider）<br>
支持的数据库<br>
I<br>
The SQL Server .NET Data Provider<br>
仅支持SQL Server7.0或更高版本<br>
<br>
II<br>
The OLE DB .NET Data Provider<br>
Access、Oracle和Sql Server等<br>
<br>
III<br>
The ODBC .NET Data Provider<br>
Access、Oracle、Sql Server、MySql、VFP等<br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表1三种数据提供者及其支持的数据库<br>
<br>
三、接下来就分别介绍以上几种数据提供者连接各种数据库<br>
<br>
<font color="#FF0000">1、&nbsp;&nbsp;&nbsp; 用The SQL Server .NET Data Provider连接数据库<br></font><br>
The SQL Server .NET Data Provider是利用SqlConnection类来连接SQL Server7.0或更高版本的数据库，<br>
<br>
SqlConnection类位于名称空间System.Data.SqlClient下。<br>
<br>
连接代码：<br>
<br>
Dim sqlConnection1 As SqlClient.SqlConnection<br>
<br>
Dim strConnect As String=”data source=服务器名;initial catalog=数据库名;user id=sa;password=;”<br>
<br>
sqlConnection1=New System.Data.SqlClient.SqlConnection(strConnect)<br>
<br>
sqlConnection1.open&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ‘打开数据库<br>
<br>
sqlConnection1.close&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ‘关闭连接，释放资源<br>
<br>
<br>
<font color="#FF0000">2、&nbsp;&nbsp;&nbsp; 用The OLE DB .NET Data Provider连接数据库</font><br>
<br>
上面已经说过，利用The OLE DB .NET Data Provider可以访问Access、Oracle和SQL Server等种数据<br>
<br>
库，那么，它是怎样访问这些数据库的呢？The OLE DB .NET Data Provider是通过位于名称空间Sy<br>
<br>
stem.Data.OleDb类库下的OleDbConnection类来连接这三种不同类型的数据库的。下面举例说明:<br>
<br>
<font color="#FF0000">1)连接SQL Server数据库</font><br>
<br>
Dim oleDbConnection1 As OleDb.OleDbConnection<br>
<br>
Dim strConnect As Sting=”Provider=SQLOLEDB;Persist Security Info=False;Data Source=服务器名;Initial Catalog=数据库名;User ID=sa;Password=;”<br>
<br>
oleDbConnection1=New System.Data.OleDb.OleDbConnection(strConnect)<br>
<br>
<br>
<font color="#FF0000">2)连接Access数据库<br></font><br>
假设要连接的Access数据库名为“Example.mdb”，存放在d:\Data\目录下。<br>
<br>
Dim oleDbConnection1 As OleDb.OleDbConnection<br>
<br>
Dim strConnect As Sting=”Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\Data\ Example.mdb”<br>
<br>
oleDbConnection1= New System.Data.OleDb.OleDbConnection(strConnect)<br>
<br>
<br>
<font color="#FF0000">3)连接Oracle数据库</font><br>
<br>
Dim oleDbConnection1 As OleDb.OleDbConnection<br>
<br>
Dim strConnect As Sting=”Provider=MSDAORA;Data Source=服务器名;User ID=用户ID;Password=密码;”<br>
<br>
oleDbConnection1= New System.Data.OleDb.OleDbConnection(strConnect)<br>
<br>
<br>
<font color="#FF0000">3、&nbsp;&nbsp;&nbsp; 用The ODBC .NET Data Provider连接数据库</font><br>
<br>
The ODBC .NET Data Provider连接数据库是通过OdbcConnection类来实现的，这个类位于名称空间<br>
<br>
Microsoft.Data.Odbc下，而名称空间Microsoft.Data.Odbc是封装在Microsoft.Data.Odbc.dll文件下的。<br>
<br>
由于篇幅有限，这里就只介绍连接Sql Server和Oracle数据库的方法，其他数据库的连接方法基本类<br>
<br>
似，我就不再多讲了。<br>
<br>
<font color="#FF0000">1)连接Sql Server数据库<br></font><br>
Dim odbcDbConnetion1 As Microsoft.Data.OdbcConnection<br>
<br>
Dim strConnect As Sting=”Driver={SQL Server};Server=服务器名;Uid=sa;pwd=;Database= 数据库名;”<br>
<br>
odbcDbConnetion1=New Microsoft.Data.OdbcConnection(strConnect)<br>
<br>
<br>
<font color="#FF0000">2)连接Oracle数据库</font><br>
<br>
Dim odbcDbConnetion1 As Microsoft.Data.OdbcConnection<br>
<br>
Dim strConnect As Sting=”Driver={Microsoft ODBC for Oracle};Server=服务器名;Uid=sa;pwd=;”<br>
<br>
odbcDbConnetion1=New Microsoft.Data.OdbcConnection(strConnect)<br>
<br>
<br>
<br>
<br>
四、总结<br>
<br>
通过本文的介绍，读者基本掌握了在Visual Basic.NET中用ADO.NET和ODBC.NET连接各种数据库的方法<br>
<br>
。以上三种驱动针对不同的数据库，它们的性能方面也有很大的不同：The SQL Server .NET Data Provider<br>
<br>
的效率最高；The OLE DB .NET Data Provider的效率比较底；The ODBC .NET Data Provider的效率最慢。</p> ]]></description>
		<eb:creationDate>2009-05-14 13:28:45</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ oracle9i学习笔记 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4154.html</link>
		<description><![CDATA[ <p style="TEXT-INDENT: 2em">create database db01</p>
<p style="TEXT-INDENT: 2em">maxlogfiles 10</p>
<p style="TEXT-INDENT: 2em">maxdatafiles 1024</p>
<p style="TEXT-INDENT: 2em">maxinstances 2</p>
<p style="TEXT-INDENT: 2em">logfile</p>
<p style="TEXT-INDENT: 2em">GROUP 1 ('/u01/oradata/db01/log_01_db01.rdo') SIZE 15M,</p>
<p style="TEXT-INDENT: 2em">GROUP 2 ('/u01/oradata/db01/log_02_db01.rdo') SIZE 15M,</p>
<p style="TEXT-INDENT: 2em">GROUP 3 ('/u01/oradata/db01/log_03_db01.rdo') SIZE 15M,</p>
<p style="TEXT-INDENT: 2em">datafile 'u01/oradata/db01/system_01_db01.dbf') SIZE 100M,</p>
<p style="TEXT-INDENT: 2em">undo tablespace UNDO</p>
<p style="TEXT-INDENT: 2em">datafile '/u01/oradata/db01/undo_01_db01.dbf' SIZE 40M</p>
<p style="TEXT-INDENT: 2em">default temporary tablespace TEMP</p>
<p style="TEXT-INDENT: 2em">tempfile '/u01/oradata/db01/temp_01_db01.dbf' SIZE 20M</p>
<p style="TEXT-INDENT: 2em">extent management local uniform size 128k</p>
<p style="TEXT-INDENT: 2em">character set AL32UTE8</p>
<p style="TEXT-INDENT: 2em">national character set AL16UTF16</p>
<p style="TEXT-INDENT: 2em">set time_zone='America/New_York';</p>
<p style="TEXT-INDENT: 2em">############### 数据字典 ##########</p>
<p style="TEXT-INDENT: 2em">set wrap off</p>
<p style="TEXT-INDENT: 2em">select * from v$dba_users;</p>
<p style="TEXT-INDENT: 2em">grant select on table_name to user/rule;</p>
<p style="TEXT-INDENT: 2em">select * from user_tables;</p>
<p style="TEXT-INDENT: 2em">select * from all_tables;</p>
<p style="TEXT-INDENT: 2em">select * from dba_tables;</p>
<p style="TEXT-INDENT: 2em">revoke dba from user_name;</p>
<p style="TEXT-INDENT: 2em">shutdown immediate</p>
<p style="TEXT-INDENT: 2em">startup nomount</p>
<p style="TEXT-INDENT: 2em">select * from v$instance;</p>
<p style="TEXT-INDENT: 2em">select * from v$sga;</p>
<p style="TEXT-INDENT: 2em">select * from v$tablespace;</p>
<p style="TEXT-INDENT: 2em">alter session set nls_language=american;</p>
<p style="TEXT-INDENT: 2em">alter database mount;</p>
<p style="TEXT-INDENT: 2em">select * from v$database;</p>
<p style="TEXT-INDENT: 2em">alter database open;</p>
<p style="TEXT-INDENT: 2em">desc dictionary</p>
<p style="TEXT-INDENT: 2em">select * from dict;</p>
<p style="TEXT-INDENT: 2em">desc v$fixed_table;</p>
<p style="TEXT-INDENT: 2em">select * from v$fixed_table;</p>
<p style="TEXT-INDENT: 2em">set oracle_sid=foxconn</p>
<p style="TEXT-INDENT: 2em">select * from dba_objects;</p>
<p style="TEXT-INDENT: 2em">set serveroutput on</p>
<p style="TEXT-INDENT: 2em">execute dbms_output.put_line('sfasd');</p>
<p style="TEXT-INDENT: 2em">############# 控制文件 ###########</p>
<p style="TEXT-INDENT: 2em">select * from v$database;</p>
<p style="TEXT-INDENT: 2em">select * from v$tablespace;</p>
<p style="TEXT-INDENT: 2em">select * from v$logfile;</p>
<p style="TEXT-INDENT: 2em">select * from v$log;</p>
<p style="TEXT-INDENT: 2em">select * from v$backup;</p>
<p style="TEXT-INDENT: 2em">/*备份用户表空间*/</p>
<p style="TEXT-INDENT: 2em">alter tablespace users begin backup;</p>
<p style="TEXT-INDENT: 2em">select * from v$archived_log;</p>
<p style="TEXT-INDENT: 2em">select * from v$controlfile;</p>
<p style="TEXT-INDENT: 2em">alter system set control_files='$ORACLE_HOME/oradata/u01/ctrl01.ctl',</p>
<p style="TEXT-INDENT: 2em">'$ORACLE_HOME/oradata/u01/ctrl02.ctl' scope=spfile;</p>
<p style="TEXT-INDENT: 2em">cp $ORACLE_HOME/oradata/u01/ctrl01.ctl $ORACLE_HOME/oradata/u01/ctrl02.ctl</p>
<p style="TEXT-INDENT: 2em">startup pfile='../initSID.ora'</p>
<p style="TEXT-INDENT: 2em">select * from v$parameter where name like 'control%' ;</p>
<p style="TEXT-INDENT: 2em">show parameter control;</p>
<p style="TEXT-INDENT: 2em">select * from v$controlfile_record_section;</p>
<p style="TEXT-INDENT: 2em">select * from v$tempfile;</p>
<p style="TEXT-INDENT: 2em">/*备份控制文件*/</p>
<p style="TEXT-INDENT: 2em">alter database backup controlfile to '../filepath/control.bak';</p>
<p style="TEXT-INDENT: 2em">/*备份控制文件，并将二进制控制文件变为了asc 的文本文件*/</p>
<p style="TEXT-INDENT: 2em">alter database backup controlfile to trace;</p>
<p style="TEXT-INDENT: 2em">############### redo log ##############</p>
<p style="TEXT-INDENT: 2em">archive log list;</p>
<p style="TEXT-INDENT: 2em">alter system archive log start;--启动自动存档</p>
<p style="TEXT-INDENT: 2em">alter system switch logfile;--强行进行一次日志switch</p>
<p style="TEXT-INDENT: 2em">alter system checkpoint;--强制进行一次checkpoint</p>
<p style="TEXT-INDENT: 2em">alter tablspace users begin backup;</p>
<p style="TEXT-INDENT: 2em">alter tablespace offline;</p>
<p style="TEXT-INDENT: 2em">/*checkpoint 同步频率参数FAST_START_MTTR_TARGET,同步频率越高，系统恢复所需时间越短*/</p>
<p style="TEXT-INDENT: 2em">show parameter fast;</p>
<p style="TEXT-INDENT: 2em">show parameter log_checkpoint;</p>
<p style="TEXT-INDENT: 2em">/*加入一个日志组*/</p>
<p style="TEXT-INDENT: 2em">alter database add logfile group 3 ('/$ORACLE_HOME/oracle/ora_log_file6.rdo' size 10M);</p>
<p style="TEXT-INDENT: 2em">/*加入日志组的一个成员*/</p>
<p style="TEXT-INDENT: 2em">alter database add logfile member '/$ORACLE_HOME/oracle/ora_log_file6.rdo' to group 3;</p>
<p style="TEXT-INDENT: 2em">/*删除日志组:当前日志组不能删；活动的日志组不能删；非归档的日志组不能删*/</p>
<p style="TEXT-INDENT: 2em">alter database drop logfile group 3;</p>
<p style="TEXT-INDENT: 2em">/*删除日志组中的某个成员，但每个组的最后一个成员不能被删除*/</p>
<p style="TEXT-INDENT: 2em">alter databse drop logfile member '$ORACLE_HOME/oracle/ora_log_file6.rdo';</p>
<p style="TEXT-INDENT: 2em">/*清除在线日志*/</p>
<p style="TEXT-INDENT: 2em">alter database clear logfile '$ORACLE_HOME/oracle/ora_log_file6.rdo';</p>
<p style="TEXT-INDENT: 2em">alter database clear logfile group 3;</p>
<p style="TEXT-INDENT: 2em">/*清除非归档日志*/</p>
<p style="TEXT-INDENT: 2em">alter database clear unarchived logfile group 3;</p>
<p style="TEXT-INDENT: 2em">/*重命名日志文件*/</p>
<p style="TEXT-INDENT: 2em">alter database rename file '$ORACLE_HOME/oracle/ora_log_file6.rdo' to '$ORACLE_HOME/oracle/ora_log_file6a.rdo';</p>
<p style="TEXT-INDENT: 2em">show parameter db_create;</p>
<p style="TEXT-INDENT: 2em">alter system set db_create_online_log_dest_1='path_name';</p>
<p style="TEXT-INDENT: 2em">select * from v$log;</p>
<p style="TEXT-INDENT: 2em">select * from v$logfile;</p>
<p style="TEXT-INDENT: 2em">/*数据库归档模式到非归档模式的互换,要启动到mount状态下才能改变;startup mount;</p>
<p style="TEXT-INDENT: 2em">然后再打开数据库.*/</p>
<p style="TEXT-INDENT: 2em">alter database noarchivelog/archivelog;</p>
<p style="TEXT-INDENT: 2em">achive log start;---启动自动归档</p>
<p style="TEXT-INDENT: 2em">alter system archive all;－－手工归档所有日志文件</p>
<p style="TEXT-INDENT: 2em">select * from v$archived_log;</p>
<p style="TEXT-INDENT: 2em">show parameter log_archive;</p>
<p style="TEXT-INDENT: 2em">###### 分析日志文件logmnr ##############</p>
<p style="TEXT-INDENT: 2em">1) 在init.ora中set utl_file_dir 参数</p>
<p style="TEXT-INDENT: 2em">2) 重新启动oracle</p>
<p style="TEXT-INDENT: 2em">3) create 目录文件</p>
<p style="TEXT-INDENT: 2em">desc dbms_logmnr_d;</p>
<p style="TEXT-INDENT: 2em">dbms_logmnr_d.build;</p>
<p style="TEXT-INDENT: 2em">4) 加入日志文件 add/remove log file</p>
<p style="TEXT-INDENT: 2em">dhms_logmnr.add_logfile</p>
<p style="TEXT-INDENT: 2em">dbms_logmnr.removefile</p>
<p style="TEXT-INDENT: 2em">5) start logmnr</p>
<p style="TEXT-INDENT: 2em">dbms_logmnr.start_logmnr</p>
<p style="TEXT-INDENT: 2em">6) 分析出来的内容查询 v$logmnr_content --sqlredo/sqlundo</p>
<p style="TEXT-INDENT: 2em">实践：</p>
<p style="TEXT-INDENT: 2em">desc dbms_logmnr_d;</p>
<p style="TEXT-INDENT: 2em">/*对数据表做一些操作，为恢复操作做准备*/</p>
<p style="TEXT-INDENT: 2em">update 表 set qty=10 where stor_id=6380;</p>
<p style="TEXT-INDENT: 2em">delete 表 where stor_id=7066;</p>
<p style="TEXT-INDENT: 2em">/***********************************/</p>
<p style="TEXT-INDENT: 2em">utl_file_dir的路径</p>
<p style="TEXT-INDENT: 2em">execute dbms_logmnr_d.build('foxdict.ora','$ORACLE_HOME/oracle/admin/fox/cdump');</p>
<p style="TEXT-INDENT: 2em">execute dbms_logmnr.add_logfile('$ORACLE_HOME/oracle/ora_log_file6.log',dbms_logmnr.newfile);</p>
<p style="TEXT-INDENT: 2em">execute dbms_logmnr.start_logmnr(dictfilename=&gt;;'$ORACLE_HOME/oracle/admin/fox/cdump/foxdict.ora');</p>
<p style="TEXT-INDENT: 2em">######### tablespace ##############</p>
<p style="TEXT-INDENT: 2em">select * form v$tablespace;</p>
<p style="TEXT-INDENT: 2em">select * from v$datafile;</p>
<p style="TEXT-INDENT: 2em">/*表空间和数据文件的对应关系*/</p>
<p style="TEXT-INDENT: 2em">select t1.name,t2.name from v$tablespace t1,v$datafile t2 where t1.ts#=t2.ts#;</p>
<p style="TEXT-INDENT: 2em">alter tablespace users add datafile 'path' size 10M;</p>
<p style="TEXT-INDENT: 2em">select * from dba_rollback_segs;</p>
<p style="TEXT-INDENT: 2em">/*限制用户在某表空间的使用限额*/</p>
<p style="TEXT-INDENT: 2em">alter user user_name quota 10m on tablespace_name;</p>
<p style="TEXT-INDENT: 2em">create tablespace xxx [datafile 'path_name/datafile_name'] [size xxx] [extent management local/dictionary] [default storage(xxx)];</p>
<p style="TEXT-INDENT: 2em">exmple: create tablespace userdata datafile '$ORACLE_HOME/oradata/userdata01.dbf' size 100M AUTOEXTEND ON NEXT 5M MAXSIZE 200M;</p>
<p style="TEXT-INDENT: 2em">create tablespace userdata datafile '$ORACLE_HOME/oradata/userdata01.dbf' size 100M extent management dictionary default storage(initial 100k next 100k pctincrease 10) offline;</p>
<p style="TEXT-INDENT: 2em">/*9i以后，oracle建议使用local管理，而不使用dictionary管理，因为local采用bitmap管理表空间 ，不会产生系统表空间的自愿争用;*/</p>
<p style="TEXT-INDENT: 2em">create tablespace userdata datafile '$ORACLE_HOME/oradata/userdata01.dbf' size 100M extent management local uniform size 1m;</p>
<p style="TEXT-INDENT: 2em">create tablespace userdata datafile '$ORACLE_HOME/oradata/userdata01.dbf' size 100M extent management local autoallocate;</p>
<p style="TEXT-INDENT: 2em">/*在创建表空间时，设置表空间内的段空间管理模式，这里用的是自动管理*/</p>
<p style="TEXT-INDENT: 2em">create tablespace userdata datafile '$ORACLE_HOME/oradata/userdata01.dbf' size 100M extent management local uniform size 1m segment space management auto;</p>
<p style="TEXT-INDENT: 2em">alter tablespace userdata mininum extent 10;</p>
<p style="TEXT-INDENT: 2em">alter tablespace userdata default storage(initial 1m next 1m pctincrease 20);</p>
<p style="TEXT-INDENT: 2em">/*undo tablespace(不能被用在字典管理模下) */</p>
<p style="TEXT-INDENT: 2em">create undo tablespace undo1 datafile '$ORACLE_HOME/oradata/undo101.dbf' size 40M extent management local;</p>
<p style="TEXT-INDENT: 2em">show parameter undo;</p>
<p style="TEXT-INDENT: 2em">/*temporary tablespace*/</p>
<p style="TEXT-INDENT: 2em">create temporary tablespace userdata tempfile '$ORACLE_HOME/oradata/undo101.dbf' size 10m extent management local;</p>
<p style="TEXT-INDENT: 2em">*设置数据库缺省的临时表空间*/</p>
<p style="TEXT-INDENT: 2em">alter database default temporary tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*系统/临时/在线的undo表空间不能被offline*/</p>
<p style="TEXT-INDENT: 2em">alter tablespace tablespace_name offline/online;</p>
<p style="TEXT-INDENT: 2em">alter tablespace tablespace_name read only;</p>
<p style="TEXT-INDENT: 2em">/*重命名用户表空间*/</p>
<p style="TEXT-INDENT: 2em">alter tablespace tablespace_name rename datafile '$ORACLE_HOME/oradata/undo101.dbf' to '$ORACLE_HOME/oradata/undo102.dbf';</p>
<p style="TEXT-INDENT: 2em">/*重命名系统表空间 ,但在重命名前必须将数据库shutdown,并重启到mount状态*/</p>
<p style="TEXT-INDENT: 2em">alter database rename file '$ORACLE_HOME/oradata/system01.dbf' to '$ORACLE_HOME/oradata/system02.dbf';</p>
<p style="TEXT-INDENT: 2em">drop tablespace userdata including contents and datafiles;---drop tablespce</p>
<p style="TEXT-INDENT: 2em">/*resize tablespace,autoextend datafile space*/</p>
<p style="TEXT-INDENT: 2em">alter database datafile '$ORACLE_HOME/oradata/undo102.dbf' autoextend on next 10m maxsize 500M;</p>
<p style="TEXT-INDENT: 2em">/*resize datafile*/</p>
<p style="TEXT-INDENT: 2em">alter database datafile '$ORACLE_HOME/oradata/undo102.dbf' resize 50m;</p>
<p style="TEXT-INDENT: 2em">/*给表空间扩展空间*/</p>
<p style="TEXT-INDENT: 2em">alter tablespace userdata add datafile '$ORACLE_HOME/oradata/undo102.dbf' size 10m;</p>
<p style="TEXT-INDENT: 2em">/*将表空间设置成OMF状态*/</p>
<p style="TEXT-INDENT: 2em">alter system set db_create_file_dest='$ORACLE_HOME/oradata';</p>
<p style="TEXT-INDENT: 2em">create tablespace userdata;---use OMF status to create tablespace;</p>
<p style="TEXT-INDENT: 2em">drop tablespace userdata;---user OMF status to drop tablespace;</p>
<p style="TEXT-INDENT: 2em">select * from dba_tablespace/v$tablespace/dba_data_files;</p>
<p style="TEXT-INDENT: 2em">/*将表的某分区移动到另一个表空间*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name move partition partition_name tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">###### ORACLE storage structure and relationships #########</p>
<p style="TEXT-INDENT: 2em">/*手工分配表空间段的分区(extend)大小*/</p>
<p style="TEXT-INDENT: 2em">alter table kong.test12 allocate extent(size 1m datafile '$ORACLE_HOME/oradata/undo102.dbf');</p>
<p style="TEXT-INDENT: 2em">alter table kong.test12 deallocate unused; ---释放表中没有用到的分区</p>
<p style="TEXT-INDENT: 2em">show parameter db;</p>
<p style="TEXT-INDENT: 2em">alter system set db_8k_cache_size=10m; ---配置8k块的内存空间块参数</p>
<p style="TEXT-INDENT: 2em">select * from dba_extents/dba_segments/data_tablespace;</p>
<p style="TEXT-INDENT: 2em">select * from dba_free_space/dba_data_file/data_tablespace;</p>
<p style="TEXT-INDENT: 2em">/*数据对象所占用的字节数*/</p>
<p style="TEXT-INDENT: 2em">select sum(bytes) from dba_extents where onwer='kong' and segment_name ='table_name';</p>
<p style="TEXT-INDENT: 2em">############ UNDO Data ################</p>
<p style="TEXT-INDENT: 2em">show parameter undo;</p>
<p style="TEXT-INDENT: 2em">alter tablespace users offline normal;</p>
<p style="TEXT-INDENT: 2em">alter tablespace users offline immediate;</p>
<p style="TEXT-INDENT: 2em">recover datafile '$ORACLE_HOME/oradata/undo102.dbf';</p>
<p style="TEXT-INDENT: 2em">alter tablespace users online ;</p>
<p style="TEXT-INDENT: 2em">select * from dba_rollback_segs;</p>
<p style="TEXT-INDENT: 2em">alter system set undo_tablespace=undotbs1;</p>
<p style="TEXT-INDENT: 2em">/*忽略回滚段的错误提示*/</p>
<p style="TEXT-INDENT: 2em">alter system set undo_suppress_errors=true;</p>
<p style="TEXT-INDENT: 2em">/*在自动管理模式下,不会真正建立rbs1;在手工管理模式则可以建立,且是私有回滚段*/</p>
<p style="TEXT-INDENT: 2em">create rollback segment rbs1 tablespace undotbs;</p>
<p style="TEXT-INDENT: 2em">desc dbms_flashback;</p>
<p style="TEXT-INDENT: 2em">/*在提交了修改的数据后,9i提供了旧数据的回闪操作,将修改前的数据只读给用户看,但这部分数据不会又恢复在表中,而是旧数据的一个映射*/</p>
<p style="TEXT-INDENT: 2em">execute dbms_flashback.enable_at_time('26-JAN-04:12:17:00 pm');</p>
<p style="TEXT-INDENT: 2em">execute dbms_flashback.disable;</p>
<p style="TEXT-INDENT: 2em">/*回滚段的统计信息*/</p>
<p style="TEXT-INDENT: 2em">select end_time,begin_time,undoblks from v$undostat;</p>
<p style="TEXT-INDENT: 2em">/*undo表空间的大小计算公式: UndoSpace=[UR * (UPS * DBS)] + (DBS * 24)</p>
<p style="TEXT-INDENT: 2em">UR :UNDO_RETENTION 保留的时间(秒)</p>
<p style="TEXT-INDENT: 2em">UPS :每秒的回滚数据块</p>
<p style="TEXT-INDENT: 2em">DBS:系统EXTENT和FILE SIZE(也就是db_block_size)*/</p>
<p style="TEXT-INDENT: 2em">select * from dba_rollback_segs/v$rollname/v$rollstat/v$undostat/v$session/v$transaction;</p>
<p style="TEXT-INDENT: 2em">show parameter transactions;</p>
<p style="TEXT-INDENT: 2em">show parameter rollback;</p>
<p style="TEXT-INDENT: 2em">/*在手工管理模式下,建立公共的回滚段*/</p>
<p style="TEXT-INDENT: 2em">create public rollback segment prbs1 tablespace undotbs;</p>
<p style="TEXT-INDENT: 2em">alter rollback segment rbs1 online;----在手工管理模式</p>
<p style="TEXT-INDENT: 2em">/*在手工管理模式中,initSID.ora中指定 undo_management=manual 、rollback_segment=('rbs1','rbs2',...)、</p>
<p style="TEXT-INDENT: 2em">transactions=100 、transactions_per_rollback_segment=10</p>
<p style="TEXT-INDENT: 2em">然后 shutdown immediate ,startup pfile=....\???.ora */</p>
<p style="TEXT-INDENT: 2em">########## Managing Tables ###########</p>
<p style="TEXT-INDENT: 2em">/*char type maxlen=2000;varchar2 type maxlen=4000 bytes</p>
<p style="TEXT-INDENT: 2em">rowid 是18位的64进制字符串 (10个bytes 80 bits)</p>
<p style="TEXT-INDENT: 2em">rowid组成: object#(对象号)--32bits,6位</p>
<p style="TEXT-INDENT: 2em">rfile#(相对文件号)--10bits,3位</p>
<p style="TEXT-INDENT: 2em">block#(块号)--22bits,6位</p>
<p style="TEXT-INDENT: 2em">row#(行号)--16bits,3位</p>
<p style="TEXT-INDENT: 2em">64进制: A-Z,a-z,0-9,/,+ 共64个符号</p>
<p style="TEXT-INDENT: 2em"></p>
<p style="TEXT-INDENT: 2em">dbms_rowid 包中的函数可以提供对rowid的解释*/</p>
<p style="TEXT-INDENT: 2em"></p>
<p style="TEXT-INDENT: 2em">select rowid,dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_row_number(rowid) from table_name;</p>
<p style="TEXT-INDENT: 2em">create table test2</p>
<p style="TEXT-INDENT: 2em">(</p>
<p style="TEXT-INDENT: 2em">id int,</p>
<p style="TEXT-INDENT: 2em">lname varchar2(20) not null,</p>
<p style="TEXT-INDENT: 2em">fname varchar2(20) constraint ck_1 check(fname like 'k%'),</p>
<p style="TEXT-INDENT: 2em">empdate date default sysdate)</p>
<p style="TEXT-INDENT: 2em">) tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">create global temporary table test2 on commit delete/preserve rows as select * from kong.authors;</p>
<p style="TEXT-INDENT: 2em">create table user.table(...) tablespace tablespace_name storage(...) pctfree10 pctused 40;</p>
<p style="TEXT-INDENT: 2em">alter table user.tablename pctfree 20 pctused 50 storage(...);---changing table storage</p>
<p style="TEXT-INDENT: 2em">/*手工分配分区,分配的数据文件必须是表所在表空间内的数据文件*/</p>
<p style="TEXT-INDENT: 2em">alter table user.table_name allocate extent(size 500k datafile '...');</p>
<p style="TEXT-INDENT: 2em">/*释放表中没有用到的空间*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name deallocate unused;</p>
<p style="TEXT-INDENT: 2em">alter table table_name deallocate unused keep 8k;</p>
<p style="TEXT-INDENT: 2em">/*将非分区表的表空间搬到新的表空间,在移动表空间后，原表中的索引对象将会不可用，必须重建*/</p>
<p style="TEXT-INDENT: 2em">alter table user.table_name move tablespace new_tablespace_name;</p>
<p style="TEXT-INDENT: 2em">create index index_name on user.table_name(column_name) tablespace users;</p>
<p style="TEXT-INDENT: 2em">alter index index_name rebuild;</p>
<p style="TEXT-INDENT: 2em">drop table table_name [CASCADE CONSTRAINTS];</p>
<p style="TEXT-INDENT: 2em">alter table user.table_name drop column col_name [CASCADE CONSTRAINTS CHECKPOINT 1000];---drop column</p>
<p style="TEXT-INDENT: 2em">/*给表中不用的列做标记*/</p>
<p style="TEXT-INDENT: 2em">alter table user.table_name set unused column comments CASCADE CONSTRAINTS;</p>
<p style="TEXT-INDENT: 2em">/*drop表中不用的做了标记列*/</p>
<p style="TEXT-INDENT: 2em">alter table user.table_name drop unused columns checkpoint 1000;</p>
<p style="TEXT-INDENT: 2em">/*当在drop col是出现异常，使用CONTINUE，防止重删前面的column*/</p>
<p style="TEXT-INDENT: 2em">ALTER TABLE USER.TABLE_NAME DROP COLUMNS CONTINUE CHECKPOINT 1000;</p>
<p style="TEXT-INDENT: 2em">select * from dba_tables/dba_objects;</p>
<p style="TEXT-INDENT: 2em">######## managing indexes ##########</p>
<p style="TEXT-INDENT: 2em">/*create index*/</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">/*创建一般索引*/</p>
<p style="TEXT-INDENT: 2em">create index index_name on table_name(column_name) tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*创建位图索引*/</p>
<p style="TEXT-INDENT: 2em">create bitmap index index_name on table_name(column_name1,column_name2) tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*索引中不能用pctused*/</p>
<p style="TEXT-INDENT: 2em">create [bitmap] index index_name on table_name(column_name) tablespace tablespace_name pctfree 20 storage(inital 100k next 100k) ;</p>
<p style="TEXT-INDENT: 2em">/*大数据量的索引最好不要做日志*/</p>
<p style="TEXT-INDENT: 2em">create [bitmap] index index_name table_name(column_name1,column_name2) tablespace_name pctfree 20 storage(inital 100k next 100k) nologging;</p>
<p style="TEXT-INDENT: 2em">/*创建反转索引*/</p>
<p style="TEXT-INDENT: 2em">create index index_name on table_name(column_name) reverse;</p>
<p style="TEXT-INDENT: 2em">/*创建函数索引*/</p>
<p style="TEXT-INDENT: 2em">create index index_name on table_name(function_name(column_name)) tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*建表时创建约束条件*/</p>
<p style="TEXT-INDENT: 2em">create table user.table_name(column_name number(7) constraint constraint_name primary key deferrable using index storage(initial 100k next 100k) tablespace tablespace_name,column_name2 varchar2(25) constraint constraint_name not null,column_name3 number(7)) tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*给创建bitmap index分配的内存空间参数，以加速建索引*/</p>
<p style="TEXT-INDENT: 2em">show parameter create_bit;</p>
<p style="TEXT-INDENT: 2em">/*改变索引的<a href="http://www.storworld.com/" target="_blank">存储</a>参数*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name pctfree 30 storage(initial 200k next 200k);</p>
<p style="TEXT-INDENT: 2em">/*给索引手工分配一个分区*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name allocate extent (size 200k datafile '$ORACLE/oradata/..');</p>
<p style="TEXT-INDENT: 2em">/*释放索引中没用的空间*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name deallocate unused;</p>
<p style="TEXT-INDENT: 2em">/*索引重建*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name rebuild tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*普通索引和反转索引的互换*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name rebuild tablespace tablespace_name reverse;</p>
<p style="TEXT-INDENT: 2em">/*重建索引时，不锁表*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name rebuild online;</p>
<p style="TEXT-INDENT: 2em">/*给索引整理碎片*/</p>
<p style="TEXT-INDENT: 2em">alter index index_name COALESCE;</p>
<p style="TEXT-INDENT: 2em">/*分析索引,事实上是更新统计的过程*/</p>
<p style="TEXT-INDENT: 2em">analyze index index_name validate structure;</p>
<p style="TEXT-INDENT: 2em">desc index_state;</p>
<p style="TEXT-INDENT: 2em">drop index index_name;</p>
<p style="TEXT-INDENT: 2em">alter index index_name monitoring usage;-----监视索引是否被用到</p>
<p style="TEXT-INDENT: 2em">alter index index_name nomonitoring usage;----取消监视</p>
<p style="TEXT-INDENT: 2em">/*有关索引信息的视图*/</p>
<p style="TEXT-INDENT: 2em">select * from dba_indexes/dba_ind_columns/dbs_ind_expressions/v$object_usage;</p>
<p style="TEXT-INDENT: 2em">########## 数据完整性的管理(Maintaining data integrity) ##########</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop constraint constraint_name;----drop 约束</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint constraint_name primary key(column_name1,column_name2);-----创建主键</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint constraint_name unique(column_name1,column_name2);---创建唯一约束</p>
<p style="TEXT-INDENT: 2em">/*创建外键约束*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint constraint_name foreign key(column_name1) references table_name(column_name1);</p>
<p style="TEXT-INDENT: 2em">/*不效验老数据，只约束新的数据[enable/disable：约束/不约束新数据;novalidate/validate:不对/对老数据进行验证]*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint constraint_name check(column_name like 'B%') enable/disable novalidate/validate;</p>
<p style="TEXT-INDENT: 2em">/*修改约束条件，延时验证，commit时验证*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name modify constraint constraint_name initially deferred;</p>
<p style="TEXT-INDENT: 2em">/*修改约束条件，立即验证*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name modify constraint constraint_name initially immediate;</p>
<p style="TEXT-INDENT: 2em">alter session set constraints=deferred/immediate;</p>
<p style="TEXT-INDENT: 2em">/*drop一个有外键的主键表,带cascade constraints参数级联删除*/</p>
<p style="TEXT-INDENT: 2em">drop table table_name cascade constraints;</p>
<p style="TEXT-INDENT: 2em">/*当truncate外键表时，先将外键设为无效，再truncate;*/</p>
<p style="TEXT-INDENT: 2em">truncate table table_name;</p>
<p style="TEXT-INDENT: 2em">/*设约束条件无效*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name disable constraint constraint_name;</p>
<p style="TEXT-INDENT: 2em">alter table table_name enable novalidate constraint constraint_name;</p>
<p style="TEXT-INDENT: 2em">/*将无效约束的数据行放入exception的表中，此表记录了违反数据约束的行的行号；在此之前，要先建exceptions表*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint constraint_name check(column_name &gt;;15) enable validate exceptions into exceptions;</p>
<p style="TEXT-INDENT: 2em">/*运行创建exceptions表的脚本*/</p>
<p style="TEXT-INDENT: 2em">start $ORACLE_HOME/rdbms/admin/utlexcpt.sql;</p>
<p style="TEXT-INDENT: 2em">/*获取约束条件信息的表或视图*/</p>
<p style="TEXT-INDENT: 2em">select * from user_constraints/dba_constraints/dba_cons_columns;</p>
<p style="TEXT-INDENT: 2em">################## managing password security and resources ####################</p>
<p style="TEXT-INDENT: 2em">alter user user_name account unlock/open;----锁定/打开用户;</p>
<p style="TEXT-INDENT: 2em">alter user user_name password expire;---设定口令到期</p>
<p style="TEXT-INDENT: 2em">/*建立口令配置文件,failed_login_attempts口令输多少次后锁，password_lock_times指多少天后口令被自动解锁*/</p>
<p style="TEXT-INDENT: 2em">create profile profile_name limit failed_login_attempts 3 password_lock_times 1/1440;</p>
<p style="TEXT-INDENT: 2em">/*创建口令配置文件*/</p>
<p style="TEXT-INDENT: 2em">create profile profile_name limit failed_login_attempts 3 password_lock_time unlimited password_life_time 30 password_reuse_time 30 password_verify_function verify_function password_grace_time 5;</p>
<p style="TEXT-INDENT: 2em">/*建立资源配置文件*/</p>
<p style="TEXT-INDENT: 2em">create profile prfile_name limit session_per_user 2 cpu_per_session 10000 idle_time 60 connect_time 480;</p>
<p style="TEXT-INDENT: 2em">alter user user_name profile profile_name;</p>
<p style="TEXT-INDENT: 2em">/*设置口令解锁时间*/</p>
<p style="TEXT-INDENT: 2em">alter profile profile_name limit password_lock_time 1/24;</p>
<p style="TEXT-INDENT: 2em">/*password_life_time指口令文件多少时间到期，password_grace_time指在第一次成功登录后到口令到期有多少天时间可改变口令*/</p>
<p style="TEXT-INDENT: 2em">alter profile profile_name limit password_lift_time 2 password_grace_time 3;</p>
<p style="TEXT-INDENT: 2em">/*password_reuse_time指口令在多少天内可被重用,password_reuse_max口令可被重用的最大次数*/</p>
<p style="TEXT-INDENT: 2em">alter profile profile_name limit password_reuse_time 10[password_reuse_max 3];</p>
<p style="TEXT-INDENT: 2em">alter user user_name identified by input_password;-----修改用户口令</p>
<p style="TEXT-INDENT: 2em">drop profile profile_name;</p>
<p style="TEXT-INDENT: 2em">/*建立了profile后，且指定给某个用户，则必须用CASCADE才能删除*/</p>
<p style="TEXT-INDENT: 2em">drop profile profile_name CASCADE;</p>
<p style="TEXT-INDENT: 2em">alter system set resource_limit=true;---启用自愿限制,缺省是false</p>
<p style="TEXT-INDENT: 2em">/*配置资源参数*/</p>
<p style="TEXT-INDENT: 2em">alter profile profile_name limit cpu_per_session 10000 connect_time 60 idle_time 5;</p>
<p style="TEXT-INDENT: 2em">/*资源参数(session级)</p>
<p style="TEXT-INDENT: 2em">cpu_per_session 每个session占用cpu的时间 单位1/100秒</p>
<p style="TEXT-INDENT: 2em">sessions_per_user 允许每个用户的并行session数</p>
<p style="TEXT-INDENT: 2em">connect_time 允许连接的时间 单位分钟</p>
<p style="TEXT-INDENT: 2em">idle_time 连接被空闲多少时间后，被自动断开 单位分钟</p>
<p style="TEXT-INDENT: 2em">logical_reads_per_session 读块数</p>
<p style="TEXT-INDENT: 2em">private_sga 用户能够在SGA中使用的私有的空间数 单位bytes</p>
<p style="TEXT-INDENT: 2em">(call级)</p>
<p style="TEXT-INDENT: 2em">cpu_per_call 每次(1/100秒)调用cpu的时间</p>
<p style="TEXT-INDENT: 2em">logical_reads_per_call 每次调用能够读的块数</p>
<p style="TEXT-INDENT: 2em">*/</p>
<p style="TEXT-INDENT: 2em">alter profile profile_name limit cpu_per_call 1000 logical_reads_per_call 10;</p>
<p style="TEXT-INDENT: 2em">desc dbms_resouce_manager;---资源管理器包</p>
<p style="TEXT-INDENT: 2em">/*获取资源信息的表或视图*/</p>
<p style="TEXT-INDENT: 2em">select * from dba_users/dba_profiles;</p>
<p style="TEXT-INDENT: 2em">###### Managing users ############</p>
<p style="TEXT-INDENT: 2em">show parameter os;</p>
<p style="TEXT-INDENT: 2em">create user testuser1 identified by kxf_001;</p>
<p style="TEXT-INDENT: 2em">grant connect,createtable to testuser1;</p>
<p style="TEXT-INDENT: 2em">alter user testuser1 quota 10m on tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*创建用户*/</p>
<p style="TEXT-INDENT: 2em">create user user_name identified by password default tablespace tablespace_name temporary tablespace tablespace_name quota 15m on tablespace_name password expire;</p>
<p style="TEXT-INDENT: 2em">/*数据库级设定缺省临时表空间*/</p>
<p style="TEXT-INDENT: 2em">alter database default temporary tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*制定数据库级的缺省表空间*/</p>
<p style="TEXT-INDENT: 2em">alter database default tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*创建os级审核的用户，需知道os_authent_prefix，表示oracle和os口令对应的前缀,'OPS$'为此参数的值，此值可以任意设置*/</p>
<p style="TEXT-INDENT: 2em">create user user_name identified by externally default OPS$tablespace_name tablespace_name temporary tablespace tablespace_name quota 15m on tablespace_name password expire;</p>
<p style="TEXT-INDENT: 2em">/*修改用户使用表空间的限额,回滚表空间和临时表空间不允许授予限额*/</p>
<p style="TEXT-INDENT: 2em">alter user user_name quota 5m on tablespace_name;</p>
<p style="TEXT-INDENT: 2em">/*删除用户或删除级联用户(用户对象下有对象的要用CASCADE，将其下一些对象一起删除)*/</p>
<p style="TEXT-INDENT: 2em">drop user user_name [CASCADE];</p>
<p style="TEXT-INDENT: 2em">/*每个用户在哪些表空间下有些什么限额*/</p>
<p style="TEXT-INDENT: 2em">desc dba_ts_quotas;select * from dba_ts_quotas where username='...';</p>
<p style="TEXT-INDENT: 2em">/*改变用户的缺省表空间*/</p>
<p style="TEXT-INDENT: 2em">alter user user_name default tablespace tablespace_name;</p>
<p style="TEXT-INDENT: 2em">######### Managing Privileges #############</p>
<p style="TEXT-INDENT: 2em">grant create table,create session to user_name;</p>
<p style="TEXT-INDENT: 2em">grant create any table to user_name; revoke create any table from user_name;</p>
<p style="TEXT-INDENT: 2em">/*授予权限语法,public 标识所有用户,with admin option允许能将权限授予第三者的权限*/</p>
<p style="TEXT-INDENT: 2em">grant system_privs,[......] to [user/role/public],[....] [with admin option];</p>
<p style="TEXT-INDENT: 2em">select * from v$pwfile_users;</p>
<p style="TEXT-INDENT: 2em">/*当 O7_dictionary_accessiblity参数为True时，标识select any table时，包括系统表也能select ,否则，不包含系统表;缺省为false*/</p>
<p style="TEXT-INDENT: 2em">show parameter O7;</p>
<p style="TEXT-INDENT: 2em">/*由于 O7_dictionary_accessiblity为静态参数，不能动态改变，故加scope=spfile,下次启动时才生效*/</p>
<p style="TEXT-INDENT: 2em">alter system set O7_dictionary_accessiblity=true scope=spfile;</p>
<p style="TEXT-INDENT: 2em">/*授予对象中的某些字段的权限，如select 某表中的某些字段的权限*/</p>
<p style="TEXT-INDENT: 2em">grant [object_privs(column,....)],[...] on object_name to user/role/public,... with grant option;</p>
<p style="TEXT-INDENT: 2em">/*oracle不允许授予select某列的权限,但可以授insert ,update某列的权限*/</p>
<p style="TEXT-INDENT: 2em">grant insert(column_name1,column_name2,...) on table_name to user_name with grant option;</p>
<p style="TEXT-INDENT: 2em">select * from dba_sys_privs/session_privs/dba_tab_privs/user_tab_privs/dba_col_privs/user_col_privs;</p>
<p style="TEXT-INDENT: 2em">/*db/os/none 审计被记录在 数据库/操作系统/不审计 缺省是none*/</p>
<p style="TEXT-INDENT: 2em">show parameter audit_trail;</p>
<p style="TEXT-INDENT: 2em">/*启动对表的select动作*/</p>
<p style="TEXT-INDENT: 2em">audit select on user.table_name by session;</p>
<p style="TEXT-INDENT: 2em">/*by session在每个session中发出command只记录一次，by access则每个command都记录*/</p>
<p style="TEXT-INDENT: 2em">audit [create table][select/update/insert on object by session/access][whenever successful/not successful];</p>
<p style="TEXT-INDENT: 2em">desc dbms_fga;---进一步设计，则可使用dbms_fgs包</p>
<p style="TEXT-INDENT: 2em">/*取消审计*/</p>
<p style="TEXT-INDENT: 2em">noaudit select on user.table_name;</p>
<p style="TEXT-INDENT: 2em">/*查被审计信息*/</p>
<p style="TEXT-INDENT: 2em">select * from all_def_audit_opts/dba_stmt_audit_opts/dba_priv_audit_opts/dba_obj_audit_opts;</p>
<p style="TEXT-INDENT: 2em">/*获取审计记录*/</p>
<p style="TEXT-INDENT: 2em">select * from dba_audit_trail/dba_audit_exists/dba_audit_object/dba_audit_session/dba_audit_statement;</p>
<p style="TEXT-INDENT: 2em">########### Managing Role #################</p>
<p style="TEXT-INDENT: 2em">create role role_name; grant select on table_name to role_name; grant role_name to user_name; set role role_name;</p>
<p style="TEXT-INDENT: 2em">create role role_name;</p>
<p style="TEXT-INDENT: 2em">create role role_name identified by password;</p>
<p style="TEXT-INDENT: 2em">create role role_name identified externally;</p>
<p style="TEXT-INDENT: 2em">set role role_name ; ----激活role</p>
<p style="TEXT-INDENT: 2em">set role role_name identified by password;</p>
<p style="TEXT-INDENT: 2em">alter role role_name not identified;</p>
<p style="TEXT-INDENT: 2em">alter role role_name identified by password;</p>
<p style="TEXT-INDENT: 2em">alter role role_name identified externally;</p>
<p style="TEXT-INDENT: 2em">grant priv_name to role_name [WITH ADMIN OPTION];</p>
<p style="TEXT-INDENT: 2em">grant update(column_name1,col_name2,...) on table_name to role_name;</p>
<p style="TEXT-INDENT: 2em">grant role_name1 to role_name2;</p>
<p style="TEXT-INDENT: 2em">/*建立default role,用户登录时，缺省激活default role*/</p>
<p style="TEXT-INDENT: 2em">alter user user_name default role role_name1,role_name2,...;</p>
<p style="TEXT-INDENT: 2em">alter user user_name default role all;</p>
<p style="TEXT-INDENT: 2em">alter user user_name default role all except role_name1,...;</p>
<p style="TEXT-INDENT: 2em">alter user user_name default role none;</p>
<p style="TEXT-INDENT: 2em">set role role1 [identified by password],role2,....;</p>
<p style="TEXT-INDENT: 2em">set role all;</p>
<p style="TEXT-INDENT: 2em">set role except role1,role2,...;</p>
<p style="TEXT-INDENT: 2em">set role none;</p>
<p style="TEXT-INDENT: 2em">revoke role_name from user_name;</p>
<p style="TEXT-INDENT: 2em">revoke role_name from public;</p>
<p style="TEXT-INDENT: 2em">drop role role_name;</p>
<p style="TEXT-INDENT: 2em">select * from dba_roles/dba_role_privs/role_role_privs/dba_sys_privs/role_sys_privs/role_tab_privs/session_roles;</p>
<p style="TEXT-INDENT: 2em">########### Basic SQL SELECT ################</p>
<p style="TEXT-INDENT: 2em">select col_name as col_alias from table_name ;</p>
<p style="TEXT-INDENT: 2em">select col_name from table_name where col1 like '_o%'; ----'_'匹配单个字符</p>
<p style="TEXT-INDENT: 2em">/*使用字符函数(右边截取,字段中包含某个字符,左边填充某字符到固定位数,右边填充某字符到固定位数)*/</p>
<p style="TEXT-INDENT: 2em">select substr(col1,-3,5),instr(col2,'g'),LPAD(col3,10,'$'),RPAD(col4,10,'%') from table_name;</p>
<p style="TEXT-INDENT: 2em">/*使用数字函数(往右/左几位四舍五入,取整,取余)*/</p>
<p style="TEXT-INDENT: 2em">select round(col1,-2),trunc(col2),mod(col3) from table_name ;</p>
<p style="TEXT-INDENT: 2em">/*使用日期函数(计算两个日期间相差几个星期,两个日期间相隔几个月,在某个月份上加几个月,某个日期的下一个日期,</p>
<p style="TEXT-INDENT: 2em">某日期所在月的最后的日期,对某个日期的月分四舍五入，对某个日期的月份进行取整)*/</p>
<p style="TEXT-INDENT: 2em">select (sysdate-col1)/7 week,months_between(sysdate,col1),add_months(col1,2),next_day(sysdate,'FRIDAY'),last_day(sysdate),</p>
<p style="TEXT-INDENT: 2em">round(sysdate,'MONTH'),trunc(sysdate,'MONTH') from table_name;</p>
<p style="TEXT-INDENT: 2em">/*使用NULL函数(当expr1为空取expr2/当expr1为空取expr2,否则取expr3/当expr1=expr2返回空)*/</p>
<p style="TEXT-INDENT: 2em">select nvl(expr1,expr2),nvl2(expr1,expr2,expr3),nullif(expr1,expr2) from table_name;</p>
<p style="TEXT-INDENT: 2em">select column1,column2,column3, case column2 when '50' then column2*1.1</p>
<p style="TEXT-INDENT: 2em">when '30' then column2*2.1</p>
<p style="TEXT-INDENT: 2em">when '10' then column3/20</p>
<p style="TEXT-INDENT: 2em">else column3</p>
<p style="TEXT-INDENT: 2em">end as ttt</p>
<p style="TEXT-INDENT: 2em">from table_name ; ------使用case函数</p>
<p style="TEXT-INDENT: 2em"></p>
<p style="TEXT-INDENT: 2em">select table1.col1,table2.col2 from table1</p>
<p style="TEXT-INDENT: 2em">[CROSS JOIN table2] | -----笛卡儿连接</p>
<p style="TEXT-INDENT: 2em">[NATURAL JOIN table2] | -----用两个表中的同名列连接</p>
<p style="TEXT-INDENT: 2em">[JOIN table2 USING (column_name)] | -----用两个表中的同名列中的某一列或几列连接</p>
<p style="TEXT-INDENT: 2em">[JOIN table2</p>
<p style="TEXT-INDENT: 2em">ON (table1.col1=table2.col2)] |</p>
<p style="TEXT-INDENT: 2em">[LEFT|RIGHT|FULL OUTER JOIN table2 ------相当于(+)=,=(+)连接,全外连接</p>
<p style="TEXT-INDENT: 2em">ON (table1.col1=table2.col2)]; ------SQL 1999中的JOIN语法;</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">select col1,col2 from table1 t1</p>
<p style="TEXT-INDENT: 2em">join table2 t2</p>
<p style="TEXT-INDENT: 2em">on t1.col1=t2.col2 and t1.col3=t2.col1</p>
<p style="TEXT-INDENT: 2em">join table3 t3</p>
<p style="TEXT-INDENT: 2em">on t2.col1=t3.col3;</p>
<p style="TEXT-INDENT: 2em">select * from table_name where col1 &lt; any (select col2 from table_name2 where continue group by col3);</p>
<p style="TEXT-INDENT: 2em">select * from table_name where col1 &lt; all (select col2 from table_name2 where continue group by col3);</p>
<p style="TEXT-INDENT: 2em">insert into (select col1,col2,col3 form table_name where col1&gt;; 50 with check option) values (value1,value2,value3);</p>
<p style="TEXT-INDENT: 2em">MERGE INTO table_name table1</p>
<p style="TEXT-INDENT: 2em">USING table_name2 table2</p>
<p style="TEXT-INDENT: 2em">ON (table1.col1=table2.col2)</p>
<p style="TEXT-INDENT: 2em">WHEN MATCHED THEN</p>
<p style="TEXT-INDENT: 2em">UPDATE SET</p>
<p style="TEXT-INDENT: 2em">table1.col1=table2.col2,</p>
<p style="TEXT-INDENT: 2em">table1.col2=table2.col3,</p>
<p style="TEXT-INDENT: 2em">...</p>
<p style="TEXT-INDENT: 2em">WHEN NOT MATCHED THEN</p>
<p style="TEXT-INDENT: 2em">INSERT VALUES(table2.col1,table2.col2,table2.col3,...); -----合并语句</p>
<p style="TEXT-INDENT: 2em">##################### CREATE/ALTER TABLE #######################</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop column column_name ;---drop column</p>
<p style="TEXT-INDENT: 2em">alter table table_name set unused (col1,col2,...);----设置列无效，这个比较快。</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop unused columns;---删除被设为无效的列</p>
<p style="TEXT-INDENT: 2em">rename table_name1 to table_name2; ---重命名表</p>
<p style="TEXT-INDENT: 2em">comment on table table_name is 'comment message';----给表放入注释信息</p>
<p style="TEXT-INDENT: 2em">create table table_name</p>
<p style="TEXT-INDENT: 2em">(col1 int not null,col2 varchar2(20),col3 varchar2(20),</p>
<p style="TEXT-INDENT: 2em">constraint uk_test2_1 unique(col2,col3))); -----定义表中的约束条件</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint pk_test2 primary key(col1,col2,...); ----创建主键</p>
<p style="TEXT-INDENT: 2em">/*建立外键*/</p>
<p style="TEXT-INDENT: 2em">create table table_name (rid int,name varchar2(20),constraint fk_test3 foreign key(rid) references other_table_name(id));</p>
<p style="TEXT-INDENT: 2em">alter table table_name add constraint ck_test3 check(name like 'K%');</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop constraint constraint_name;</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop primary key cascade;----级联删除主键</p>
<p style="TEXT-INDENT: 2em">alter table table_name disable/enable constraint constraint_name;----使约束暂时无效</p>
<p style="TEXT-INDENT: 2em">/*删除列，并级联删除此列下的约束条件*/</p>
<p style="TEXT-INDENT: 2em">alter table table_name drop column column_name cascade constraint;</p>
<p style="TEXT-INDENT: 2em">select * from user_constraints/user_cons_columns;---约束条件相关视图</p>
<p style="TEXT-INDENT: 2em">############## Create Views #####################</p>
<p style="TEXT-INDENT: 2em">CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name [(alias[,alias]...)]</p>
<p style="TEXT-INDENT: 2em">AS subquery</p>
<p style="TEXT-INDENT: 2em">[WITH CHECK OPTION [CONSTRAINT constraint_name]]</p>
<p style="TEXT-INDENT: 2em">[WITH READ ONLY [CONSTRAINT constraint_name]]; ------创建视图的语法</p>
<p style="TEXT-INDENT: 2em">example: Create or replace view testview as select col1,col2,col3 from table_name; ------创建视图</p>
<p style="TEXT-INDENT: 2em">/*使用别名*/</p>
<p style="TEXT-INDENT: 2em">Create or replace view testview as select col1,sum(col2) col2_alias from table_name;</p>
<p style="TEXT-INDENT: 2em">/*创建复杂视图*/</p>
<p style="TEXT-INDENT: 2em">Create view view_name (alias1,alias2,alias3,alias4) as select d.col1,min(e.col1),max(e.col1),avg(e.col1) from table_name1 e,table_name2 d where e.col2=d.col2 group by d.col1;</p>
<p style="TEXT-INDENT: 2em">/*当用update修改数据时，必须满足视图的col1&gt;;10的条件，不满足则不能被改变.*/</p>
<p style="TEXT-INDENT: 2em">Create or replace view view_name as select * from table_name where col1&gt;;10 with check option;</p>
<p style="TEXT-INDENT: 2em">/*改变视图的值.对于简单视图可以用update语法修改表数据，但复杂视图则不一定能改。如使用了函数，group by ,distinct等的列*/</p>
<p style="TEXT-INDENT: 2em">update view_name set col1=value1;</p>
<p style="TEXT-INDENT: 2em">/*TOP-N分析*/</p>
<p style="TEXT-INDENT: 2em">select [column_list],rownum from (select [column_list] from table_name order by Top-N_column) where rownum&lt;=N;</p>
<p style="TEXT-INDENT: 2em">/*找出某列三条最大值的记录*/</p>
<p style="TEXT-INDENT: 2em">example: select rownum as rank ,col1 ,col2 from (select col1 ,col2 from table_name order by col2 desc) where rownum&lt;=3;</p>
<p style="TEXT-INDENT: 2em">############# Other database Object ###############</p>
<p style="TEXT-INDENT: 2em">CREATE SEQUENCE sequence_name [INCREMENT BY n]</p>
<p style="TEXT-INDENT: 2em">[START WITH n]</p>
<p style="TEXT-INDENT: 2em">[{MAXVALUE n | NOMAXVALUE}]</p>
<p style="TEXT-INDENT: 2em">[{MINVALUE n | NOMINVALUE}]</p>
<p style="TEXT-INDENT: 2em">[{CYCEL | NOCYCLE}]</p>
<p style="TEXT-INDENT: 2em">[{CACHE n | NOCACHE}]; -----创建SEQUENCE</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">CREATE SEQUENCE sequence_name INCREMENT BY 10</p>
<p style="TEXT-INDENT: 2em">START WITH 120</p>
<p style="TEXT-INDENT: 2em">MAXVALUE 9999</p>
<p style="TEXT-INDENT: 2em">NOCACHE</p>
<p style="TEXT-INDENT: 2em">NOCYCLE;</p>
<p style="TEXT-INDENT: 2em">select * from user_sequences ;---当前用户下记录sequence的视图</p>
<p style="TEXT-INDENT: 2em">select sequence_name.nextval,sequence_name.currval from dual;-----sequence的引用</p>
<p style="TEXT-INDENT: 2em">alter sequence sequence_name INCREMENT BY 20</p>
<p style="TEXT-INDENT: 2em">MAXVALUE 999999</p>
<p style="TEXT-INDENT: 2em">NOCACHE</p>
<p style="TEXT-INDENT: 2em">NOCYCLE; -----修改sequence,不能改变起始序号</p>
<p style="TEXT-INDENT: 2em">drop sequence sequence_name; ----删除sequence</p>
<p style="TEXT-INDENT: 2em">CREATE [PUBLIC] SYNONYM synonym_name FOR object; ------创建同义词</p>
<p style="TEXT-INDENT: 2em">DROP [PUBLIC] SYNONYM synonym_name;----删除同义词</p>
<p style="TEXT-INDENT: 2em">CREATE PUBLIC DATABASE LINK link_name USEING OBJECT;----创建DBLINK</p>
<p style="TEXT-INDENT: 2em">select * from object_name@link_name; ----访问远程数据库中的对象</p>
<p style="TEXT-INDENT: 2em">/*union 操作，它将两个集合的交集部分压缩，并对数据排序*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,col3 from table1_name union select col1,col2,col3 from table2_name;</p>
<p style="TEXT-INDENT: 2em">/*union all 操作，两个集合的交集部分不压缩，且不对数据排序*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,col3 from table1_name union all select col1,col2,col3 from table2_name;</p>
<p style="TEXT-INDENT: 2em">/*intersect 操作，求两个集合的交集,它将对重复数据进行压缩，且排序*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,col3 from table1_name intersect select col1,col2,col3 from table2_name;</p>
<p style="TEXT-INDENT: 2em">/*minus 操作，集合减,它将压缩两个集合减后的重复记录, 且对数据排序*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,col3 from table1_name minus select col1,col2,col3 from table2_name;</p>
<p style="TEXT-INDENT: 2em">/*EXTRACT 抽取时间函数. 此例是抽取当前日期中的年*/</p>
<p style="TEXT-INDENT: 2em">select EXTRACT(YEAR FROM SYSDATE) from dual;</p>
<p style="TEXT-INDENT: 2em">/*EXTRACT 抽取时间函数. 此例是抽取当前日期中的月*/</p>
<p style="TEXT-INDENT: 2em">select EXTRACT(MONTH FROM SYSDATE) from dual;</p>
<p style="TEXT-INDENT: 2em">########################## 增强的 group by 子句 #########################</p>
<p style="TEXT-INDENT: 2em">select [column,] group_function(column)...</p>
<p style="TEXT-INDENT: 2em">from table</p>
<p style="TEXT-INDENT: 2em">[WHERE condition]</p>
<p style="TEXT-INDENT: 2em">[GROUP BY [ROLLUP] group_by_expression]</p>
<p style="TEXT-INDENT: 2em">[HAVING having_expression];</p>
<p style="TEXT-INDENT: 2em">[ORDER BY column]; -------ROLLUP操作字，对group by子句的各字段从右到左进行再聚合</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">/*其结果看起来象对col1做小计*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3) from table group by rollup(col1,col2);</p>
<p style="TEXT-INDENT: 2em">/*复合rollup表达式*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3) from table group by rollup((col1,col2));</p>
<p style="TEXT-INDENT: 2em">select [column,] group_function(column)...</p>
<p style="TEXT-INDENT: 2em">from table</p>
<p style="TEXT-INDENT: 2em">[WHERE condition]</p>
<p style="TEXT-INDENT: 2em">[GROUP BY [CUBE] group_by_expression]</p>
<p style="TEXT-INDENT: 2em">[HAVING having_expression];</p>
<p style="TEXT-INDENT: 2em">[ORDER BY column]; -------CUBE操作字，除完成ROLLUP的功能外，再对ROLLUP后的结果集从右到左再聚合</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">/*其结果看起来象对col1做小计后，再对col2做小计，最后算总计*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3) from table group by cube(col1,col2);</p>
<p style="TEXT-INDENT: 2em">/*复合rollup表达式*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3) from table group by cube((col1,col2));</p>
<p style="TEXT-INDENT: 2em">/*混合rollup,cube表达式*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,col3,sum(col4) from table group by col1,rollup(col2),cube(col3);</p>
<p style="TEXT-INDENT: 2em">/*GROUPING(expr)函数，查看select语句种以何字段聚合，其取值为0或1*/</p>
<p style="TEXT-INDENT: 2em">select [column,] group_function(column)...,GROUPING(expr)</p>
<p style="TEXT-INDENT: 2em">from table</p>
<p style="TEXT-INDENT: 2em">[WHERE condition]</p>
<p style="TEXT-INDENT: 2em">[GROUP BY [ROLLUP] group_by_expression]</p>
<p style="TEXT-INDENT: 2em">[HAVING having_expression];</p>
<p style="TEXT-INDENT: 2em">[ORDER BY column];</p>
<p style="TEXT-INDENT: 2em">example:</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3),grouping(col1),grouping(col2) from table group by cube(col1,col2);</p>
<p style="TEXT-INDENT: 2em">/*grouping sets操作，对group by结果集先对col1求和，再对col2求和，最后将其结果集并在一起*/</p>
<p style="TEXT-INDENT: 2em">select col1,col2,sum(col3) from table group by grouping sets((col1),(col2))<br></p> ]]></description>
		<eb:creationDate>2009-05-04 14:32:45</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ JSP实现上传图片 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4103.html</link>
		<description><![CDATA[ &nbsp; 文件上传类:MoqUploadBean.java &nbsp; &nbsp;<br>
&nbsp; package &nbsp; net.moq.www; &nbsp;<br>
&nbsp; import &nbsp; java.io.*; &nbsp;<br>
&nbsp; import &nbsp; java.util.*; &nbsp;<br>
&nbsp; import &nbsp; javax.servlet.*; &nbsp;<br>
&nbsp; import &nbsp; javax.servlet.http.*; &nbsp;<br>
&nbsp; /** &nbsp;<br>
&nbsp; &nbsp; * &nbsp;<br>
&nbsp; &nbsp; * &nbsp; Title: &nbsp; 文件上传类 &nbsp;<br>
&nbsp; &nbsp; * &nbsp; Description: &nbsp; 既能对文件进行上传,又能取得输入框的值,最多可同时上传255个文件 &nbsp;<br>
&nbsp; &nbsp; * &nbsp; Copyright: &nbsp; Copyright &nbsp; (c) &nbsp; 2002 &nbsp;<br>
&nbsp; &nbsp; * &nbsp; Company: &nbsp; Tekson &nbsp;<br>
&nbsp; &nbsp; * &nbsp; @author &nbsp; 莫琼 &nbsp;<br>
&nbsp; &nbsp; * &nbsp; @version &nbsp; 1.0 &nbsp;<br>
&nbsp; &nbsp; */ &nbsp;<br>
&nbsp; public &nbsp; class &nbsp; MoqUploadBean &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; sourceFile &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //源文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; suffix &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //文件后缀名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String &nbsp; canSuffix &nbsp; = &nbsp; ".gif.jpg.jpeg.png"; &nbsp; &nbsp; &nbsp; &nbsp; //可上传的文件后缀名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String &nbsp; objectPath &nbsp; = &nbsp; "c:/"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //目标文件目录 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; objectFileName &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; //目标文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; ServletInputStream &nbsp; sis &nbsp; = &nbsp; null; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入流 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; description &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; //描述状态 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; long &nbsp; size &nbsp; = &nbsp; 100 &nbsp; * &nbsp; 1024; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //限制大小 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; int &nbsp; count &nbsp; = &nbsp; 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //已传输文件数目 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; byte[] &nbsp; b &nbsp; = &nbsp; new &nbsp; byte[4096]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //字节流存放数组 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; boolean &nbsp; successful &nbsp; = &nbsp; true; &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; Hashtable &nbsp; fields &nbsp; = &nbsp; new &nbsp; Hashtable(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; MoqUploadBean() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //设置上传文件的后缀名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSuffix(String &nbsp; canSuffix) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.canSuffix &nbsp; = &nbsp; canSuffix; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //设置文件保存路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setObjectPath(String &nbsp; objectPath) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.objectPath &nbsp; = &nbsp; objectPath; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //设置文件保存路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSize(long &nbsp; maxSize) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.size &nbsp; = &nbsp; maxSize; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //文件上传处理程序 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSourceFile(HttpServletRequest &nbsp; request) &nbsp; throws &nbsp; IOException &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis &nbsp; = &nbsp; request.getInputStream(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; a &nbsp; = &nbsp; 0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; k &nbsp; = &nbsp; 0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; s &nbsp; = &nbsp; ""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("filename="")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; 取得文件数据 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; s.substring(k &nbsp; + &nbsp; 10); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k &nbsp; = &nbsp; s.indexOf("""); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; s.substring(0, &nbsp; k); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sourceFile[count] &nbsp; = &nbsp; s; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k &nbsp; = &nbsp; s.lastIndexOf("."); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suffix[count] &nbsp; = &nbsp; s.substring(k &nbsp; + &nbsp; 1); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (canTransfer(count)) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transferFile(count); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ++count; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; else &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("name="")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; 普通表单输入元素，获取输入元素名字 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; fieldName &nbsp; = &nbsp; s.substring(k+6, &nbsp; s.length()-3); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringBuffer &nbsp; fieldValue &nbsp; = &nbsp; new &nbsp; StringBuffer(b.length); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a-2); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (b[0] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[1] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[2] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[3] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[4] &nbsp; == &nbsp; 45)) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; else &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldValue.append(s); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fields.put(fieldName, &nbsp; fieldValue.toString()); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (!successful) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得表单元素值 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; getFieldValue(String &nbsp; fieldName) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (fields &nbsp; == &nbsp; null &nbsp; || &nbsp; fieldName &nbsp; == &nbsp; null) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; null; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; (String) &nbsp; fields.get(fieldName); &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得上传文件数 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; int &nbsp; getCount() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; count; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得目标路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; getObjectPath() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; objectPath; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得源文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getSourceFile() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; sourceFile; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得目标文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getObjectFileName() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; objectFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //取得上传状态描述 &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getDescription() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; description; &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //判断上传文件的类型 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; boolean &nbsp; canTransfer(int &nbsp; i) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suffix[i] &nbsp; = &nbsp; suffix[i].toLowerCase(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //这个是用来传图片的，各位可以把后缀名改掉或者不要这个条件 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (sourceFile[i].equals("") &nbsp; || &nbsp; (!(canSuffix.indexOf("."+suffix[i])&gt;=0))) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[i] &nbsp; = &nbsp; "ERR: &nbsp; File &nbsp; suffix &nbsp; is &nbsp; wrong."; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; false; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; true; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; //上传文件转换 &nbsp;<br>
&nbsp; &nbsp; &nbsp; private &nbsp; void &nbsp; transferFile(int &nbsp; i) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; x &nbsp; = &nbsp; Long.toString(new &nbsp; java.util.Date().getTime()); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectFileName[i] &nbsp; = &nbsp; x &nbsp; + &nbsp; "." &nbsp; + &nbsp; suffix[i]; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FileOutputStream &nbsp; out &nbsp; = &nbsp; new &nbsp; FileOutputStream(objectPath &nbsp; + &nbsp; objectFileName[i]); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; a &nbsp; = &nbsp; 0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; k &nbsp; = &nbsp; 0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long &nbsp; hastransfered &nbsp; = &nbsp; 0; &nbsp; //标示已经传输的字节数 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; s &nbsp; = &nbsp; ""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("Content-Type:")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (b[0] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[1] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[2] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[3] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[4] &nbsp; == &nbsp; 45)) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.write(b, &nbsp; 0, &nbsp; a); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hastransfered &nbsp; += &nbsp; a; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (hastransfered &nbsp; &gt;= &nbsp; size) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[count] &nbsp; = &nbsp; "ERR: &nbsp; The &nbsp; file &nbsp; " &nbsp; + &nbsp; sourceFile[count] &nbsp; + &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " &nbsp; is &nbsp; too &nbsp; large &nbsp; to &nbsp; transfer. &nbsp; The &nbsp; whole &nbsp; process &nbsp; is &nbsp; interrupted."; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; successful &nbsp; = &nbsp; false; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (successful) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[count] &nbsp; = &nbsp; "Right: &nbsp; The &nbsp; file &nbsp; " &nbsp; + &nbsp; sourceFile[count] &nbsp; + &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " &nbsp; has &nbsp; been &nbsp; transfered &nbsp; successfully."; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (!successful) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; File &nbsp; tmp &nbsp; = &nbsp; new &nbsp; File(objectPath &nbsp; + &nbsp; objectFileName[count]); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp.delete(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch &nbsp; (IOException &nbsp; ioe) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[i] &nbsp; = &nbsp; ioe.toString(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; public &nbsp; static &nbsp; void &nbsp; main(String[] &nbsp; args) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Test &nbsp; OK"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; 文件上传调用:MoqUpload.jsp &nbsp;<br>
&nbsp; 〈%@ &nbsp; page &nbsp; contentType="text/html; &nbsp; charset=GB2312" &nbsp; %&gt; &nbsp;<br>
&nbsp; 〈html&gt; &nbsp;<br>
&nbsp; 〈head&gt; &nbsp;<br>
&nbsp; 〈title&gt;文件上载〈/title&gt; &nbsp;<br>
&nbsp; 〈/head&gt; &nbsp;<br>
&nbsp; 〈body&gt; &nbsp;<br>
&nbsp; 〈form &nbsp; action="MoqUploadSubmit.jsp" &nbsp; enctype="MULTIPART/FORM-DATA" &nbsp; method="post"&gt; &nbsp;<br>
&nbsp; 作者姓名:〈input &nbsp; type="text" &nbsp; name="Author" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 公司名称:〈input &nbsp; type="text" &nbsp; name="Company" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 文件描述:〈input &nbsp; type="text" &nbsp; name="Comment" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 选择文件1:〈input &nbsp; type="file" &nbsp; name="filename1" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 选择文件2:〈input &nbsp; type="file" &nbsp; name="filename2" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 选择文件3:〈input &nbsp; type="file" &nbsp; name="filename3" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 选择文件4:〈input &nbsp; type="file" &nbsp; name="filename4" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈br &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈input &nbsp; type="submit" &nbsp; value="上载" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈/form&gt; &nbsp;<br>
&nbsp; 〈/body&gt; &nbsp;<br>
&nbsp; 〈/html&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; 文件上传提交:MoqUploadSubmit.jsp &nbsp;<br>
&nbsp; 〈%@ &nbsp; page &nbsp; contentType="text/html;charset=gb2312"%&gt; &nbsp;<br>
&nbsp; 〈jsp:useBean &nbsp; id="fileBean" &nbsp; scope="page" &nbsp; class="net.moq.www.MoqUploadBean" &nbsp; /&gt; &nbsp;<br>
&nbsp; 〈% &nbsp;<br>
&nbsp; fileBean.setObjectPath("D:\\Temp\"); &nbsp;<br>
&nbsp; fileBean.setSize(10000*1024); &nbsp;<br>
&nbsp; fileBean.setSuffix(".gif.jpg.png.jpge.html.htm"); &nbsp;<br>
&nbsp; fileBean.setSourceFile(request); &nbsp;<br>
&nbsp; String &nbsp; [] &nbsp; saSourceFile &nbsp; = &nbsp; fileBean.getSourceFile(); &nbsp;<br>
&nbsp; String &nbsp; [] &nbsp; saObjectFile &nbsp; = &nbsp; fileBean.getObjectFileName(); &nbsp;<br>
&nbsp; String &nbsp; [] &nbsp; saDescription &nbsp; = &nbsp; fileBean.getDescription(); &nbsp;<br>
&nbsp; int &nbsp; iCount &nbsp; = &nbsp; fileBean.getCount(); &nbsp;<br>
&nbsp; String &nbsp; sObjectPath &nbsp; = &nbsp; fileBean.getObjectPath(); &nbsp;<br>
&nbsp; for(int &nbsp; i=0;i〈iCount;i++) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;源始文件:"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println(saSourceFile[i]); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;目标文件:"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println(sObjectPath+saObjectFile[i]); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;上传说明:"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println(saDescription[i]); &nbsp;<br>
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;"); &nbsp;<br>
&nbsp; } &nbsp;<br>
&nbsp; out.println("〈br&gt;作者:" &nbsp; + &nbsp; fileBean.getFieldValue("Author")); &nbsp;<br>
&nbsp; out.println("〈br&gt;公司:" &nbsp; + &nbsp; fileBean.getFieldValue("Company")); &nbsp;<br>
&nbsp; out.println("〈br&gt;说明:" &nbsp; + &nbsp; fileBean.getFieldValue("Comment")); &nbsp;<br>
&nbsp; %&gt;&nbsp;&nbsp;<br>
<h3><strong><a name="r_17067011">\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\</a></strong></h3>
<p>jsp &nbsp; 文件 &nbsp;<br>
&nbsp; &lt;%@ &nbsp; page &nbsp; contentType="text/html; &nbsp; charset=GB2312" &nbsp; %&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &lt;HTML&gt; &nbsp;<br>
&nbsp; &lt;head&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &lt;/head&gt; &nbsp;<br>
&nbsp; &lt;BODY &nbsp; BGCOLOR="white"&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &lt;H1&gt;文件上传&lt;/H1&gt; &nbsp;<br>
&nbsp; &lt;HR&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &lt;FORM &nbsp; name="frm" &nbsp; METHOD="post" &nbsp; ACTION="/servlet/upload.upload" &nbsp; ENCTYPE="multipart/form-data"&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; 选择上传文件 &nbsp; : &nbsp; &nbsp;<br>
&nbsp; &lt;INPUT &nbsp; TYPE="FILE" &nbsp; NAME="FILE1" &nbsp; SIZE="25"&gt;&lt;BR&gt; &nbsp;<br>
&nbsp; &lt;input &nbsp; &nbsp; type="hidden" &nbsp; name="id" &nbsp; value &nbsp; =10&gt; &nbsp;<br>
&nbsp; &lt;input &nbsp; &nbsp; type="hidden" &nbsp; name="tablename" &nbsp; value &nbsp; ="t_projmodel"&gt; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;INPUT &nbsp; type="submit" &nbsp; name="Upload" &nbsp; VALUE="Upload" &nbsp; &gt; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &lt;/FORM&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &lt;/BODY&gt; &nbsp;<br>
&nbsp; &lt;/HTML&gt; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; JAVA文件 &nbsp;<br>
&nbsp; ====================== &nbsp;<br>
&nbsp; package &nbsp; upload; &nbsp;<br>
&nbsp; import &nbsp; java.sql.*; &nbsp;<br>
&nbsp; import &nbsp; java.io.*; &nbsp;<br>
&nbsp; import &nbsp; java.util.*; &nbsp;<br>
&nbsp; import &nbsp; javax.servlet.*; &nbsp;<br>
&nbsp; import &nbsp; javax.servlet.http.*; &nbsp;<br>
&nbsp; import &nbsp; com.jspsmart.upload.*; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; public &nbsp; class &nbsp; upload &nbsp; extends &nbsp; HttpServlet{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; upload() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; private &nbsp; ServletConfig &nbsp; config; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /** &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * &nbsp; Init &nbsp; the &nbsp; servlet &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final &nbsp; public &nbsp; void &nbsp; init(ServletConfig &nbsp; config) &nbsp; throws &nbsp; ServletException &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.config &nbsp; = &nbsp; config; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final &nbsp; public &nbsp; ServletConfig &nbsp; getServletConfig() &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; config; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; doGet(HttpServletRequest &nbsp; request, &nbsp; HttpServletResponse &nbsp; response) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws &nbsp; ServletException, &nbsp; IOException &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doPost(request,response); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; doPost(HttpServletRequest &nbsp; request, &nbsp; HttpServletResponse &nbsp; response) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws &nbsp; ServletException, &nbsp; IOException &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("============UpLoad &nbsp; begin &nbsp; ddd============="); &nbsp;<br>
&nbsp; &nbsp; java.util.Date &nbsp; starttime &nbsp; = &nbsp; new &nbsp; java.util.Date(); &nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; String &nbsp; tn &nbsp; =""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; &nbsp; &nbsp; &nbsp; tn= &nbsp; "FILELIST"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; id=null; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SmartUpload &nbsp; mySmartUpload &nbsp; = &nbsp; new &nbsp; SmartUpload(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PrintWriter &nbsp; out &nbsp; = &nbsp; response.getWriter(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Class.forName("oracle.jdbc.driver.OracleDriver"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch(java.lang.ClassNotFoundException &nbsp; &nbsp; e) &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.err.print("ClassNotFoundException: &nbsp; "+e.getMessage()); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Connection &nbsp; conn &nbsp; = &nbsp; DriverManager.getConnection("jdbc:oracle:thin:@192.168.102.53:1521:china","user","pass"); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setAutoCommit(false);//设置自不自动提交。 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Statement &nbsp; stmt=conn.createStatement(ResultSet.TYPE_FORWARD_ONLY &nbsp; ,ResultSet.CONCUR_UPDATABLE); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; Initialization &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mySmartUpload.initialize(config, &nbsp; request, &nbsp; response); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mySmartUpload.setMaxFileSize(50000 &nbsp; * &nbsp; 1024); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; Upload &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mySmartUpload.upload(); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //取得text框中的数据 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Enumeration &nbsp; enumer=mySmartUpload.getRequest().getParameterNames(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while(enumer.hasMoreElements()){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; key=(String) &nbsp; enumer.nextElement(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String[] &nbsp; values=mySmartUpload.getRequest().getParameterValues(key); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(key.equals("id")){ &nbsp; //得到text框中的value值 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id=values[0]; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(key.equals("tablename")){ &nbsp; //得到text框中的value值 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tn=values[0]; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //取得文件和文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; com.jspsmart.upload.File &nbsp; myFile &nbsp; = &nbsp; mySmartUpload.getFiles().getFile(0); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; fileName=myFile.getFileName(); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!myFile.isMissing()){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //save &nbsp; data &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myFile.saveAs(fileName,mySmartUpload.SAVE_PHYSICAL); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("=======fileName="+fileName+"===="); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; java.io.File &nbsp; sfile=new &nbsp; java.io.File(fileName); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; java.io.InputStream &nbsp; inStream=new &nbsp; java.io.FileInputStream(sfile); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; i=0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; j=0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; fileSize=myFile.getSize(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("======fileSize="+fileSize+"===="); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(0!=fileSize) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //取得文件内容类型 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; contenttype &nbsp; =myFile.getContentType(); &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; &nbsp; String &nbsp; strSql="insert &nbsp; into &nbsp; FILELIST(file_id,filename,type,filebody) &nbsp; values('"+id+"','"+fileName+"',contenttype,empty_blob())"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; strSql &nbsp; ="update &nbsp; " &nbsp; +tn+ &nbsp; " &nbsp; set &nbsp; pm_name='" &nbsp; + &nbsp; fileName &nbsp; +"' &nbsp; ,pm_remark &nbsp; ='"+contenttype+"', &nbsp; pm_direc= &nbsp; empty_blob() &nbsp; where &nbsp; pm_id=" &nbsp; +id &nbsp; ; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stmt.execute(strSql); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; sql &nbsp; ="select &nbsp; pm_direc &nbsp; from &nbsp; " &nbsp; +tn+ &nbsp; " &nbsp; where &nbsp; pm_id="+id+" &nbsp; for &nbsp; update &nbsp; "; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ResultSet &nbsp; rs=stmt.executeQuery(sql); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (rs &nbsp; !=null&amp;&amp; rs.next()){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oracle.sql.BLOB &nbsp; blob &nbsp; = &nbsp; ((oracle.jdbc.OracleResultSet)rs).getBLOB("pm_direc"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputStream &nbsp; outStream &nbsp; = &nbsp; blob.getBinaryOutputStream(); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] &nbsp; bytes &nbsp; = &nbsp; new &nbsp; byte[fileSize]; &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inStream.read(bytes); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outStream.write(bytes); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outStream.flush(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stmt.execute("commit"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(outStream!=null) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outStream.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(inStream!=null) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inStream.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(stmt!=null) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stmt.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(conn!=null) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //删除临时文件 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(sfile!=null){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean &nbsp; b=sfile.delete(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(b); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; str="&lt;a &nbsp; href='javascript:history.back()'&gt;go &nbsp; back&lt;/a&gt;"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("upload &nbsp; sucess"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;"+str); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; java.util.Date &nbsp; endtime &nbsp; = &nbsp; new &nbsp; java.util.Date(); &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;start："+starttime); &nbsp; &nbsp;<br>
&nbsp; &nbsp; out.println("&lt;p&gt;end："+endtime); &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(sfile!=null)sfile.delete(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stmt.execute("rollback"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; str="&lt;a &nbsp; href='javascript:history.back()'&gt;go &nbsp; back&lt;/a&gt;"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("resultset &nbsp; is &nbsp; null!!"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;upload &nbsp; fail"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;"+str); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; str="&lt;a &nbsp; href='javascript:history.back()'&gt;go &nbsp; back&lt;/a&gt;"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(sfile!=null)sfile.delete(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stmt.execute("rollback"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("path &nbsp; error!!"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("upload &nbsp; fail"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;"+str); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; str="&lt;a &nbsp; href='javascript:history.back()'&gt;go &nbsp; back&lt;/a&gt;"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("no &nbsp; file"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;"+str); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch(Exception &nbsp; ex){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; str="&lt;a &nbsp; href='javascript:history.back()'&gt;go &nbsp; back&lt;/a&gt;"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("upload &nbsp; fail"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.println("&lt;p&gt;"+str); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("============UpLoad &nbsp; end============="); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; }</p> ]]></description>
		<eb:creationDate>2009-04-16 17:10:02</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 上传图片 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4102.html</link>
		<description><![CDATA[ &nbsp; import &nbsp; java.io.*; &nbsp;<br>
&nbsp; import &nbsp; java.util.*; &nbsp;<br>
&nbsp; import &nbsp; com.sun.image.codec.jpeg.*; &nbsp;<br>
&nbsp; import &nbsp; java.awt.image.*; &nbsp;<br>
&nbsp; import &nbsp; java.awt.*; &nbsp;<br>
&nbsp; import &nbsp; java.net.*; &nbsp;<br>
&nbsp; import &nbsp; java.applet.*; &nbsp;<br>
&nbsp; import &nbsp; java.sql.*; &nbsp;<br>
&nbsp; //缩略图类， &nbsp;<br>
&nbsp; //本java类能将jpg图片文件，进行等比或非等比的大小转换。 &nbsp;<br>
&nbsp; //具体使用方法 &nbsp;<br>
&nbsp; //s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true)) &nbsp;<br>
&nbsp; public &nbsp; class &nbsp; Small_pic{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; InputDir; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; OutputDir; &nbsp; &nbsp; &nbsp; &nbsp; //输出图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; InputFileName; &nbsp; &nbsp; &nbsp; //输入图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; OutputFileName; &nbsp; &nbsp; //输出图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; OutputWidth=80; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //默认输出图片宽 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; OutputHeight=80; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //默认输出图片高 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; rate=0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean &nbsp; proportion=true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //是否等比缩放标记(默认为等比缩放) &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; Small_pic(){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //初始化变量 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InputDir=""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputDir=""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InputFileName=""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputFileName=""; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputWidth=80; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputHeight=80; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate=0; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setInputDir(String &nbsp; InputDir){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputDir=InputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setOutputDir(String &nbsp; OutputDir){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputDir=OutputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setInputFileName(String &nbsp; InputFileName){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputFileName=InputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setOutputFileName(String &nbsp; OutputFileName){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputFileName=OutputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setOutputWidth(int &nbsp; OutputWidth){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputWidth=OutputWidth; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setOutputHeight(int &nbsp; OutputHeight){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputHeight=OutputHeight; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setW_H(int &nbsp; width,int &nbsp; height){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputWidth=width; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputHeight=height; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; s_pic(){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BufferedImage &nbsp; image; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; NewFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //建立输出文件对象 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; File &nbsp; file &nbsp; = &nbsp; new &nbsp; File(OutputDir+OutputFileName); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FileOutputStream &nbsp; tempout &nbsp; =null; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempout= &nbsp; new &nbsp; FileOutputStream(file); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch(Exception &nbsp; ex){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(ex.toString()); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Image &nbsp; img=null; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Toolkit &nbsp; tk=Toolkit.getDefaultToolkit(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Applet &nbsp; app=new &nbsp; Applet(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MediaTracker &nbsp; mt &nbsp; = &nbsp; new &nbsp; MediaTracker(app); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img=tk.getImage(InputDir+InputFileName); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mt.addImage(img, &nbsp; 0); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mt.waitForID(0); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch(Exception &nbsp; e) &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(img.getWidth(null)==-1){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(" &nbsp; &nbsp; &nbsp; can't &nbsp; read,retry!"+"&lt;BR&gt;"); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; "no"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; new_w; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; new_h; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (this.proportion==true) &nbsp; &nbsp; //判断是否是等比缩放. &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为等比缩放计算输出的图片宽度及高度 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double &nbsp; rate1=((double)img.getWidth(null))/(double)OutputWidth+0.1; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double &nbsp; rate2=((double)img.getHeight(null))/(double)OutputHeight+0.1; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double &nbsp; rate=rate1&gt;rate2?rate1:rate2; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_w=(int)(((double)img.getWidth(null))/rate); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_h=(int)(((double)img.getHeight(null))/rate); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_w=OutputWidth; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输出的图片宽度 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_h=OutputHeight; &nbsp; &nbsp; &nbsp; &nbsp; //输出的图片高度 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BufferedImage &nbsp; buffImg &nbsp; = &nbsp; new &nbsp; BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Graphics &nbsp; g &nbsp; = &nbsp; buffImg.createGraphics(); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.setColor(Color.white); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.fillRect(0,0,new_w,new_h); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.drawImage(img,0,0,new_w,new_h,null); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.dispose(); &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JPEGImageEncoder &nbsp; encoder &nbsp; = &nbsp; JPEGCodec.createJPEGEncoder(tempout); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encoder.encode(buffImg); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempout.close(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch(IOException &nbsp; ex){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(ex.toString()); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; "ok"; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; s_pic(String &nbsp; InputDir,String &nbsp; OutputDir,String &nbsp; InputFileName,String &nbsp; OutputFileName){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputDir=InputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输出图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputDir=OutputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputFileName=InputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输出图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputFileName=OutputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; s_pic(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; s_pic(String &nbsp; InputDir,String &nbsp; OutputDir,String &nbsp; InputFileName,String &nbsp; OutputFileName,int &nbsp; width,int &nbsp; height,boolean &nbsp; gp){ &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputDir=InputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输出图路径 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputDir=OutputDir; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.InputFileName=InputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输出图文件名 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.OutputFileName=OutputFileName; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //设置图片长宽 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setW_H(width,height); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //是否是等比缩放 &nbsp; 标记 &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.proportion=gp; &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; s_pic(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public &nbsp; static &nbsp; void &nbsp; main(String &nbsp; [] &nbsp; a) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp;<br>
&nbsp; //s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Small_pic &nbsp; mypic &nbsp; =new &nbsp; &nbsp; Small_pic(); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println( &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mypic.s_pic("E:\\JAVA\\J2EEDatum\\王亮jsp资料\\缩图例子\\personal\", &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "E:\\JAVA\\J2EEDatum\\王亮jsp资料\\缩图例子\\personal\", &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "1.jpg","new1.jpg",80,80,true) &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp;<br>
&nbsp; } ]]></description>
		<eb:creationDate>2009-04-16 17:06:01</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ JSP上传图片并生成缩略图 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4101.html</link>
		<description><![CDATA[ 本例子使用了jspsmart组件进行上传，这里可以免费下载该组件www.jspsmart.com<br>
下载解压后，将jar包复制到　\WEB-INF\lib　目录后重启服务器，jspsmart即可正常使用了<br>
<br>
1、uploadimage.jsp<br>
<br>
&lt;%@ page contentType="text/html;charset=gb2312" language="java" import="java.io.*,java.awt.Image,java.awt.image.*,com.sun.image.codec.jpeg.*,<br>
java.sql.*,com.jspsmart.upload.*,java.util.*,cn.oof.database.*,cn.oof.house.*"%&gt;<br>
&lt;%<br>
SmartUpload mySmartUpload =new SmartUpload();<br>
long file_size_max=4000000;<br>
String fileName2="",ext="",testvar="";<br>
String url="uploadfile/images/"; //应保证在根目录中有此目录的存在<br>
//初始化<br>
mySmartUpload.initialize(pageContext);<br>
//只允许上载此类文件<br>
try {<br>
mySmartUpload.setAllowedFilesList("jpg,gif");<br>
//上载文件<br>
mySmartUpload.upload();<br>
} catch (Exception e){<br>
%&gt;<br>
&lt;SCRIPT language=javascript&gt;<br>
alert("只允许上传.jpg和.gif类型图片文件");<br>
window.location=''upfile.jsp'';<br>
&lt;/script&gt;<br>
&lt;%<br>
}<br>
try{<br>
<br>
com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(0);<br>
if (myFile.isMissing()){%&gt;<br>
&lt;SCRIPT language=javascript&gt;<br>
alert("请先选择要上传的文件");<br>
window.location=''upfile.jsp'';<br>
&lt;/script&gt;<br>
&lt;%}<br>
else{<br>
//String myFileName=myFile.getFileName(); //取得上载的文件的文件名<br>
ext= myFile.getFileExt(); //取得后缀名<br>
int file_size=myFile.getSize(); //取得文件的大小<br>
String saveurl="";<br>
if(file_size&lt;file_size_max){<br>
//更改文件名，取得当前上传时间的毫秒数值<br>
Calendar calendar = Calendar.getInstance();<br>
String filename = String.valueOf(calendar.getTimeInMillis());<br>
saveurl=request.getRealPath("/") url;<br>
saveurl =filename "." ext; //保存路径<br>
myFile.saveAs(saveurl,mySmartUpload.SAVE_PHYSICAL);<br>
//out.print(filename);<br>
//-----------------------上传完成，开始生成缩略图-------------------------<br>
java.io.File file = new java.io.File(saveurl); //读入刚才上传的文件<br>
String newurl=request.getRealPath("/") url filename "_min." ext; //新的缩略图保存地址<br>
Image src = javax.imageio.ImageIO.read(file); //构造Image对象<br>
float tagsize=200;<br>
int old_w=src.getWidth(null); //得到源图宽<br>
int old_h=src.getHeight(null);<br>
int new_w=0;<br>
int new_h=0; //得到源图长<br>
int tempsize;<br>
float tempdouble;<br>
if(old_w&gt;old_h){<br>
tempdouble=old_w/tagsize;<br>
}else{<br>
tempdouble=old_h/tagsize;<br>
}<br>
new_w=Math.round(old_w/tempdouble);<br>
new_h=Math.round(old_h/tempdouble);//计算新图长宽<br>
BufferedImage tag = new BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB);<br>
tag.getGraphics().drawImage(src,0,0,new_w,new_h,null); //绘制缩小后的图<br>
FileOutputStream newimage=new FileOutputStream(newurl); //输出到文件流<br>
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);<br>
encoder.encode(tag); //近JPEG编码<br>
newimage.close();<br>
<br>
}<br>
else{<br>
out.print("&lt;SCRIPT language=''javascript''&gt;");<br>
out.print("alert(''上传文件大小不能超过" (file_size_max/1000) "K'');");<br>
out.print("window.location=''upfile.jsp;''");<br>
out.print("&lt;/SCRIPT&gt;");<br>
}<br>
}<br>
}catch (Exception e){<br>
<br>
e.toString();<br>
<br>
}<br>
%&gt;<br>
<br>
2 upload.htm<br>
&lt;html&gt;<br>
&lt;head&gt;<br>
&lt;title&gt;请选择上传的图片&lt;/title&gt;<br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
&lt;table border="0" align="center" cellpadding="0" cellspacing="0"&gt;<br>
&lt;tr&gt;<br>
&lt;td height="45" align="center" valign="middle"&gt;&lt;form action="uploadimage.jsp" method="post" enctype="multipart/form-data" name="form1"&gt;<br>
请选择上传的图片<br>
&lt;input type="file" name="file"&gt;<br>
&lt;input type="submit" name="Submit" value="上传"&gt;<br>
&lt;/form&gt;&lt;/td&gt;<br>
&lt;/tr&gt;<br>
&lt;/table&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;
<p>文章整理：西部数码--专业提供<a href="http://www.west263.com/services/domain">域名注册</a>、<a href="http://www.westhost.cn/" target="_blank">虚拟主机</a>服务<br>
<a href="http://www.west263.com/" target="_blank">http://www.west263.com</a><br>
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息，谢谢!<br></p> ]]></description>
		<eb:creationDate>2009-04-16 17:03:41</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 从数据库(mysql)存取图片（JSP） ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4100.html</link>
		<description><![CDATA[ <div><font color="#0000FF">关键字：mysql jsp 图片存取</font></div>
<div>为了使用JSP灵活，需要把各种文件储存到数据库中，然后需要的时候把它读取出来显示到客户端。这些文件包括音乐，图片，文本等，人们统称为二进制文件。</div>
<div>&nbsp;</div>
<div>首先，二进制文件储存到数据库的过程：打开文件，将内容读到缓冲区，然后直接联线创建jdbc语句对象，使用该缓冲区的数据，并执行更新，就完成了储存。</div>
<div>&nbsp;</div>
<div>例子：</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp; 首先在mysql中创建一个表 picture_db</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<table style="BORDER-COLLAPSE: collapse" bordercolor="#999999" cellspacing="0" cellpadding="0" width="95%" bgcolor="#F1F1F1" border="1">
<tbody>
<tr>
<td>
<p style="MARGIN: 5px; LINE-HEIGHT: 150%"><span style="COLOR: #000000"><font face="NSimSun"><span style="COLOR: #0000ff">create</span> <span style="COLOR: #0000ff">table</span> picture_db<span style="COLOR: #0000cc">(</span><br>
&nbsp;file_name <span style="COLOR: #ff0000">varchar</span><span style="COLOR: #0000cc">(</span>255<span style="COLOR: #0000cc">)</span> <span style="COLOR: #ff0000">not</span> <span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">,</span><br>
&nbsp;content longblob<span style="COLOR: #0000cc">,</span><br>
&nbsp;primary key <span style="COLOR: #0000cc">(</span>file_name<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span></font></span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>接下来就是用java写储存文件的代码：</p>
<p>假设要储存的图片名称是：01.jpg (放在同一个目录下）</p>
<p>&nbsp;</p>
<table style="BORDER-COLLAPSE: collapse" bordercolor="#999999" cellspacing="0" cellpadding="0" width="95%" bgcolor="#F1F1F1" border="1">
<tbody>
<tr>
<td>
<p style="MARGIN: 5px; LINE-HEIGHT: 150%"><span style="COLOR: #000000"><br>
<font face="NSimSun"><span style="COLOR: #0000ff">import</span> <span style="COLOR: #ff0000">java</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">sql</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #0000cc">*</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #0000ff">import</span> <span style="COLOR: #ff0000">java</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">io</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #0000cc">*</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #0000ff">import</span> <span style="COLOR: #ff0000">java</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">nio</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #0000cc">*</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #0000ff">public</span> <span style="COLOR: #0000ff">class</span> UploadImage <span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">protected</span> <span style="COLOR: #ff0000">Connection</span> dbConnection<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">protected</span> <span style="COLOR: #ff0000">String</span> driverName <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"com.mysql.jdbc.Driver"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">protected</span> <span style="COLOR: #ff0000">String</span> dbURL <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"jdbc:mysql://localhost:3306/sample_db"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;<span style="COLOR: #0000ff">protected</span> <span style="COLOR: #ff0000">String</span> userID <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"root"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;<span style="COLOR: #0000ff">protected</span> <span style="COLOR: #ff0000">String</span> passwd <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"yourpassword"</span><span style="COLOR: #0000cc">;</span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">public</span> <span style="COLOR: #0000ff">boolean</span> storeImage<span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">String</span> sqlstr<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">File</span> <span style="COLOR: #ff0000">file</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">try</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">FileInputStream</span> fin <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #ff0000">FileInputStream</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">file</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">ByteBuffer</span> nbf <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff0000">ByteBuffer</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">allocate</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #ff0000">file</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">length</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">byte</span><span style="COLOR: #0000cc">[</span><span style="COLOR: #0000cc">]</span> <span style="COLOR: #ff0000">array</span> <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #0000ff">byte</span><span style="COLOR: #0000cc">[</span>1024<span style="COLOR: #0000cc">]</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">int</span> offset <span style="COLOR: #0000cc">=</span>0<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">length</span><span style="COLOR: #0000cc">=</span>0<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">while</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">length</span><span style="COLOR: #0000cc">=</span>fin<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">read</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">array</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">&gt;</span>0<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">if</span><span style="COLOR: #0000cc">(</span>length!=1024<span style="COLOR: #0000cc">)</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nbf<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">put</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">array</span><span style="COLOR: #0000cc">,</span>0<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">length</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">else</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nbf<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">put</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">array</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset<span style="COLOR: #0000cc">+</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff0000">length</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fin<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">close</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">byte</span><span style="COLOR: #0000cc">[</span><span style="COLOR: #0000cc">]</span> content <span style="COLOR: #0000cc">=</span> nbf<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">array</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">return</span> <span style="COLOR: #ff0000">setImage</span><span style="COLOR: #0000cc">(</span>sqlstr<span style="COLOR: #0000cc">,</span>content<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">FileNotFoundException</span> e<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">printStackTrace</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span> <span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">IOException</span> e<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">printStackTrace</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">return</span> false<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">private</span> <span style="COLOR: #0000ff">boolean</span> <span style="COLOR: #ff0000">setImage</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">String</span> sqlstr<span style="COLOR: #0000cc">,</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #0000cc">[</span><span style="COLOR: #0000cc">]</span><span style="COLOR: #ff0000">in</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">boolean</span> flag <span style="COLOR: #0000cc">=</span> false<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">if</span><span style="COLOR: #0000cc">(</span>sqlstr<span style="COLOR: #0000cc">=</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">)</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlstr<span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"select * from picture_db"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">try</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">Class</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">forName</span><span style="COLOR: #0000cc">(</span>driverName<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbConnection <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff0000">DriverManager</span><span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">getConnection</span><span style="COLOR: #0000cc">(</span>dbURL<span style="COLOR: #0000cc">,</span>userID<span style="COLOR: #0000cc">,</span>passwd<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">Statement</span> stmt <span style="COLOR: #0000cc">=</span> dbConnection<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">createStatement</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">ResultSet</span><span style="COLOR: #0000cc">.</span>TYPE_SCROLL_INSENSITIVE<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">ResultSet</span><span style="COLOR: #0000cc">.</span>CONCUR_UPDATABLE<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">ResultSet</span> rs <span style="COLOR: #0000cc">=</span> stmt<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">executeQuery</span><span style="COLOR: #0000cc">(</span>sqlstr<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">if</span><span style="COLOR: #0000cc">(</span>rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">next</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">updateBytes</span><span style="COLOR: #0000cc">(</span>2<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">in</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">updateRow</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">else</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">moveToInsertRow</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">updateString</span><span style="COLOR: #0000cc">(</span>1<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff00ff">"01"</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">updateBytes</span><span style="COLOR: #0000cc">(</span>2<span style="COLOR: #0000cc">,</span><span style="COLOR: #ff0000">in</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">insertRow</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">close</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flag<span style="COLOR: #0000cc">=</span>true<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">Exception</span> e<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">printStackTrace</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">return</span> flag<span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">public</span> <span style="COLOR: #0000ff">static</span> <span style="COLOR: #0000ff">void</span> main<span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">String</span><span style="COLOR: #0000cc">[</span><span style="COLOR: #0000cc">]</span> args<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UploadImage upload <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">new</span> UploadImage<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">try</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">File</span> <span style="COLOR: #ff0000">file</span> <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #ff0000">File</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff00ff">"01.jpg"</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">if</span><span style="COLOR: #0000cc">(</span>upload<span style="COLOR: #0000cc">.</span>storeImage<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">,</span> <span style="COLOR: #ff0000">file</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">System</span><span style="COLOR: #0000cc">.</span>out<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">print</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff00ff">"ture"</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">else</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">System</span><span style="COLOR: #0000cc">.</span>out<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">print</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff00ff">"False"</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">Exception</span> e<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span><span style="COLOR: #ff0000">printStackTrace</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
<span style="COLOR: #0000cc">}</span><br></font></span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>如果执行成功的话，系统打印“true" 否则“false".</p>
<p>最后就是将图片度取出来：与储存的过程相反，它是县建立连接，创建数据库查询的jdbc对象，使用该语句来返回二进制结果，保存到文件当中。</p>
<p>showImage.jsp</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table style="BORDER-COLLAPSE: collapse" bordercolor="#999999" cellspacing="0" cellpadding="0" width="95%" bgcolor="#F1F1F1" border="1">
<tbody>
<tr>
<td>
<p style="MARGIN: 5px; LINE-HEIGHT: 150%"><span style="COLOR: #000000"><font face="NSimSun"><span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page contentType <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"image/jpeg;charset=GB2312"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page <span style="COLOR: #0000ff">import</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"java.sql.*"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page <span style="COLOR: #0000ff">import</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"java.io.*"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page <span style="COLOR: #0000ff">import</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"com.sun.image.codec.jpeg.*"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page <span style="COLOR: #0000ff">import</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"javax.imageio.*"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">@</span> page <span style="COLOR: #0000ff">import</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"java.awt.image.*"</span><span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000ff">html</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000ff">head</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000ff">meta</span> http<span style="COLOR: #0000cc">-</span>equiv<span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"Content-Type"</span> <span style="COLOR: #ff0000">content</span><span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"image/jpeg;charset=GB2312"</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000ff">title</span><span style="COLOR: #0000cc">&gt;</span>showDBImage<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">/</span><span style="COLOR: #0000ff">title</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">/</span><span style="COLOR: #0000ff">head</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000ff">body</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">%</span><br>
<span style="COLOR: #ff0000">String</span> showImage <span style="COLOR: #0000cc">=</span><span style="COLOR: #ff00ff">"select * from picture_db where file_name ='01'"</span><span style="COLOR: #0000cc">;</span><br>
Connection conn <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #ff0000">BufferedInputStream</span> inputImage <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">;</span><br>
<br>
&nbsp;<span style="COLOR: #ff0000">String</span> driverName <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"com.mysql.jdbc.Driver"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">String</span> dbURL <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"jdbc:mysql://localhost:3306/sample_db"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">String</span> userID <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"root"</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">String</span> passwd <span style="COLOR: #0000cc">=</span> <span style="COLOR: #ff00ff">"yourpassword"</span><span style="COLOR: #0000cc">;</span><br>
<br>
<br>
<br>
<span style="COLOR: #0000ff">try</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">Class</span><span style="COLOR: #0000cc">.</span>forName<span style="COLOR: #0000cc">(</span>driverName<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">.</span>newInstance<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span>&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;conn <span style="COLOR: #0000cc">=</span> DriverManager<span style="COLOR: #0000cc">.</span>getConnection<span style="COLOR: #0000cc">(</span>dbURL<span style="COLOR: #0000cc">,</span>userID<span style="COLOR: #0000cc">,</span>passwd<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;Statement st <span style="COLOR: #0000cc">=</span> conn<span style="COLOR: #0000cc">.</span>createStatement<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;ResultSet rs <span style="COLOR: #0000cc">=</span> st<span style="COLOR: #0000cc">.</span>executeQuery<span style="COLOR: #0000cc">(</span>showImage<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">while</span><span style="COLOR: #0000cc">(</span>rs<span style="COLOR: #0000cc">.</span>next<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Blob blob <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000cc">(</span>Blob<span style="COLOR: #0000cc">)</span>rs<span style="COLOR: #0000cc">.</span>getBlob<span style="COLOR: #0000cc">(</span><span style="COLOR: #ff00ff">"content"</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inputImage <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #ff0000">BufferedInputStream</span><span style="COLOR: #0000cc">(</span>blob<span style="COLOR: #0000cc">.</span>getBinaryStream<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000cc">}</span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;BufferedImage image <span style="COLOR: #0000cc">=</span> <span style="COLOR: #0000ff">null</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;image <span style="COLOR: #0000cc">=</span> ImageIO<span style="COLOR: #0000cc">.</span>read<span style="COLOR: #0000cc">(</span>inputImage<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">ServletOutputStream</span> sos <span style="COLOR: #0000cc">=</span> response<span style="COLOR: #0000cc">.</span>getOutputStream<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;JPEGImageEncoder encoder <span style="COLOR: #0000cc">=</span> JPEGCodec<span style="COLOR: #0000cc">.</span>createJPEGEncoder<span style="COLOR: #0000cc">(</span>sos<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;encoder<span style="COLOR: #0000cc">.</span>encode<span style="COLOR: #0000cc">(</span>image<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;inputImage<span style="COLOR: #0000cc">.</span>close<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #0000cc">(</span>SQLException e<span style="COLOR: #0000cc">)</span><br>
<span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span>printStackTrace<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #0000cc">}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #0000cc">(</span><span style="COLOR: #ff0000">IOException</span> e<span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">{</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;e<span style="COLOR: #0000cc">.</span>printStackTrace<span style="COLOR: #0000cc">(</span><span style="COLOR: #0000cc">)</span><span style="COLOR: #0000cc">;</span><br>
<span style="COLOR: #0000cc">}</span><br>
<span style="COLOR: #0000cc">%</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">/</span><span style="COLOR: #0000ff">body</span><span style="COLOR: #0000cc">&gt;</span><br>
<span style="COLOR: #0000cc">&lt;</span><span style="COLOR: #0000cc">/</span><span style="COLOR: #0000ff">html</span><span style="COLOR: #0000cc">&gt;</span><br></font></span></p>
</td>
</tr>
</tbody>
</table>
<p>不足之处在于：每次只能储存一张图片，好像还不能储存两张图片，它总是覆盖掉前面的那一张即使图片的文字不一样。如果感兴趣的朋友，帮我测试以下。谢谢。还有，如果我想储存多张图片，该如何呢？</p> ]]></description>
		<eb:creationDate>2009-04-16 16:41:18</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 教你如何在MySQL数据库中直接储存图片 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4099.html</link>
		<description><![CDATA[ 如果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库，那么这篇文章就是为你而写的!我将告诉你怎样通过HTML表单来储存这些文件，怎样访问和使用这些文件。
<p><font size="3">　　<strong>本文概述：</strong></font></p>
<p><font size="3">　　在mysql中建立一个新的数据库</font></p>
<p><font size="3">　　一个怎样储存文件的例子程序</font></p>
<p><font size="3">　　一个怎样访问文件的例子程序</font></p>
<p><font size="3">　　在mysql中建立一个新的database</font></p>
<p><font size="3">　　首先，你必须在你的mysql中建立一个新的数据库，我们将会把那些二进制文件储存在这个数据库里。在例子中我会使用下列结构，为了建立数据库，你必须做下列步骤：</font></p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="WORD-WRAP: break-word" bgcolor="#F3F3F3"><font size="3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br>
进入MySql控制器<br>
输入命令"create database binary_data;"<br>
输入命令"use binary_data;"<br>
输入命令"CREATE TABLE binary_data ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,<br>
description CHAR(50), bin_data LONGBLOB, filename CHAR(50), filesize CHAR(50), filetype CHAR(50));" （不能断行）</font></td>
</tr>
</tbody>
</table>
<br>
<font size="3">　　如果没有意外，数据库和表应该建立好了。</font>
<p><font size="3">　一个怎样储存文件的例子程序 用这个例子你可以通过Html表单将文件传输到数据库中。.</font></p>
<p><font size="3">　　store.php3 以下为引用的内容：</font></p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="WORD-WRAP: break-word" bgcolor="#F3F3F3"><font size="3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br>
　&lt;?php<br>
<br>
// store.php3 - by Florian Dittmer &lt;dittmer@gmx.net&gt;<br>
?&gt;<br>
<br>
&lt;HTML&gt;<br>
&lt;HEAD&gt;&lt;TITLE&gt;Store binary data into SQL Database&lt;/TITLE&gt;&lt;/HEAD&gt;<br>
&lt;BODY&gt;<br>
<br>
&lt;?php<br>
// 如果提交了表单，代码将被执行:<br>
<br>
if ($submit) {<br>
<br>
&nbsp;&nbsp; // 连接到数据库<br>
&nbsp;&nbsp; // (你可能需要调整主机名，用户名和密码)<br>
<br>
&nbsp;&nbsp; MYSQL_CONNECT( "localhost", "root", "password");<br>
&nbsp;&nbsp; mysql_select_db( "binary_data");<br>
<br>
&nbsp;&nbsp; $data = addslashes(fread(fopen($form_data, "r"), filesize($form_data)));<br>
<br>
&nbsp;&nbsp; $result=MYSQL_QUERY( "INSERT INTO binary_data (description,bin_data,filename,filesize,filetype) ".<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "VALUES (’$form_description’,’$data’,’$form_data_name’,’$form_data_size’,’$form_data_type’)");<br>
<br>
&nbsp;&nbsp; $id= mysql_insert_id();<br>
&nbsp;&nbsp; print "&lt;p&gt;This file has the following Database ID: &lt;b&gt;$id&lt;/b&gt;";<br>
<br>
&nbsp;&nbsp; MYSQL_CLOSE();<br>
<br>
} else {<br>
<br>
&nbsp;&nbsp; // 否则显示储存新数据的表单<br>
?&gt;<br>
<br>
&nbsp;&nbsp; &lt;form method="post" action=" &lt;?php echo $PHP_SELF; ?&gt;" enctype="multipart/form-data"&gt;<br>
&nbsp;&nbsp; File Description:&lt;br&gt;<br>
&nbsp;&nbsp; &lt;input type="text" name="form_description" size="40"&gt;<br>
&nbsp;&nbsp; &lt;INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="1000000"&gt;<br>
&nbsp;&nbsp; &lt;br&gt;File to upload/store in database:&lt;br&gt;<br>
&nbsp;&nbsp; &lt;input type="file" name="form_data" size="40"&gt;<br>
&nbsp;&nbsp; &lt;p&gt;&lt;input type="submit" name="submit" value="submit"&gt;<br>
&nbsp;&nbsp; &lt;/form&gt;<br>
<br>
&lt;?php<br>
<br>
}<br>
<br>
?&gt;<br>
<br>
&lt;/BODY&gt;<br>
&lt;/HTML&gt;</font></td>
</tr>
</tbody>
</table>
<font size="3">　　如果你执行了这个程序，你将会看见一个简单的Html表单，单击“浏览”选择一个文件，然后单击提交。</font>
<p><font size="3">　　当文件上传至web服务器之后，程序将会告诉你刚刚上传的文件的ID，记住这个ID，待会要用的。</font></p>
<p><font size="3">　　一个怎样访问文件的例子程序</font></p>
<p><font size="3">　　你可以通过这个程序访问你刚才储存的文件</font></p>
<p><font size="3">　　以下为引用的内容：</font></p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="WORD-WRAP: break-word" bgcolor="#F3F3F3"><font size="3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br>
　&lt;?php<br>
<br>
// getdata.php3 - by Florian Dittmer &lt;dittmer@gmx.net&gt;<br>
// 调用方法: getdata.php3?id=&lt;id&gt;<br>
<br>
if($id) {<br>
<br>
&nbsp;&nbsp; // 你可能需要调整主机名，用户名和密码:<br>
&nbsp;&nbsp; @MYSQL_CONNECT( "localhost", "root", "password");<br>
<br>
&nbsp;&nbsp; @mysql_select_db( "binary_data");<br>
<br>
&nbsp;&nbsp; $query = "select bin_data,filetype from binary_data where id=$id";<br>
&nbsp;&nbsp; $result = @MYSQL_QUERY($query);<br>
<br>
&nbsp;&nbsp; $data = @MYSQL_RESULT($result,0, "bin_data");<br>
&nbsp;&nbsp; $type = @MYSQL_RESULT($result,0, "filetype");<br>
<br>
&nbsp;&nbsp; Header( "Content-type: $type");<br>
&nbsp;&nbsp; echo $data;<br>
<br>
};<br>
?&gt;</font></td>
</tr>
</tbody>
</table>
<p><font size="3">　　程序必须知道要访问那个文件， 你必须将ID作为一个参数。</font></p>
<p><font size="3">例如: 一个文件在数据库中的ID为2. 你可以这样调用它:</font></p>
<p><font size="3">　　getdata.php3?id=2如果你将图片储存在数据库里, 你可以向调用图片一样调用它。</font></p>
<p><font size="3">　　Example: 一个图片文件在数据库中的ID为3. 你可以这样调用它:</font></p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="WORD-WRAP: break-word" bgcolor="#F3F3F3"><font size="3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br>
&lt;img src="getdata.php3?id=3"&gt;</font></td>
</tr>
</tbody>
</table>
<p><font size="3">　　怎样储存大于1MB的文件:</font></p>
<p><font size="3">　　如果你想储存大于1MB的文件，你必须对你的程序、PHP设置、SQL设置进行许多修改，。</font></p>
<p><font size="3">　　下面几条也许可以帮助你储存小于24MB的文件：</font></p>
<p><font size="3">　　修改 store.php3 ，将 MAX_FILE_SIZE 的值改成 24000000。</font></p>
<p><font size="3">　　修改你的PHP设置，在一般情况下，PHP只允许小于2MB的文件，你必须将max_filesize(在php.ini中)的值改成24000000</font></p>
<p><font size="3">　　去掉MYSQL的数据包大小限制,在一般情况下 MYSQL 小于1 MB的数据包.</font></p>
<p><font size="3">　　你必须用以下参数重启你的MYSQL</font></p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="WORD-WRAP: break-word" bgcolor="#F3F3F3"><font size="3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br>
/usr/local/bin/safe_mysqld -O key_buffer=16M -O table_cache=128 -O sort_buffer=4M -O record_buffer=1M -O max_allowed_packet=24M</font></td>
</tr>
</tbody>
</table> ]]></description>
		<eb:creationDate>2009-04-16 16:38:31</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ dll中去掉依赖 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4080.html</link>
		<description><![CDATA[ <strong>由向导生成的一个win32普通的DLL工程，编译之后依赖到msvcr80.dll/msvcr80d.dll，如何才能去掉这个依赖？<br>
之前用VS2003的时候好像就没有看到这个依赖dll，非常的奇怪。</strong>
<hr style="BORDER-TOP: #336699 1px dotted; HEIGHT: 0px" noshade>
<strong>这个问题第1个回答：</strong><br>
在项目设置中先改成静态连接MFC，编译一下后再改回使用标准库。
<hr style="BORDER-TOP: #336699 1px dotted; HEIGHT: 0px" noshade>
<b>这个问题第2个回答：</b><br>
说个最简单的办法<br>
在项目属性中-&gt;&nbsp;C/C++&nbsp;-&gt;&nbsp;代码生成&nbsp;-&gt;&nbsp;运行时库<br>
使用&nbsp;多线程/Mt&nbsp;或者&nbsp;多线程调试/Mtd&nbsp;编译出来都不依赖动态链接库(MSVCR80(D).DLL&nbsp;for&nbsp;VC8)<br>
而使用多线程DLL&nbsp;/MD&nbsp;或者多线程DLL调试/MDd&nbsp;编译出来则需要相应的动态链接库<br>
<br>
在VC8中，如果使用/mt(d)，编译出来的文件将会增大debug大约400多K，release大约50K<br>
不过50K无所谓吧<br>
<br>
如果你对这多出来的50K很不爽，或者真的有要求<br>
你可以在release项目设置中使用/MD选项,并且做一些改变，使编译出来的程序动态链接&nbsp;MSVCR.DLL&nbsp;而不是&nbsp;MSVCR80.DLL<br>
具体做法如下:<br>
从VC6中找来对应的库:MSVCRT.LIB/MSVCRTD.LIB(调试)&nbsp;,注意，我指的是VC6的，VC8的名字一样但是版本完全不同的<br>
你可以从网上找找下载过来，VC6的MSVCRT.LIB大约是231K<br>
找来之后，放在你项目的随便一个目录中，然后在项目的连接选项里指定附加这个输入目录<br>
这时你重新编译一下项目，可能会提示你很多诸如"error&nbsp;LNK2019:&nbsp;无法解析的外部符号"之类的错误:<br>
你需要关闭编译器的几个选项:<br>
1.基本运行时检查&nbsp;使用默认值<br>
2.缓冲区安全检查&nbsp;关闭<br>
<br>
<br>
这样编译出来的程序你查看导入表使用的则是msvcr.dll,但是不推荐这么做...<br>
<br>
<br>
<hr style="BORDER-TOP: #336699 1px dotted; HEIGHT: 0px" noshade>
<b>这个问题第3个回答：</b><br>
带d的表示是debug版本，你在发布时不应该发布debug版本，而应该改成release版本编译发布（调试时用debug版本）<br>
<br>
至于另外一个文件，这是要求在部署的机器上安装vc运行时和.net&nbsp;redistribution&nbsp;包的，这个不安装是不行的
<hr style="BORDER-TOP: #336699 1px dotted; HEIGHT: 0px" noshade>
<b>这个问题第4个回答：</b><br>
注意查看选项&nbsp;把需要的库编译到文件里而不是连接到文件即可!
<hr style="BORDER-TOP: #336699 1px dotted; HEIGHT: 0px" noshade>
<b>这个问题第5个回答：</b><br>
把编译环境&nbsp;设置成控制台程序即可 ]]></description>
		<eb:creationDate>2009-04-06 16:50:18</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 个人收藏的编程下载资源 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/4000.html</link>
		<description><![CDATA[ <p><span href="http://www.vckbase.com">http://www.vckbase.com<br>
这个网站就不用多说了，学习vc必去之地。网站专门提供了免费的ftp下载，好东东巨多！<br>
<br>
vc之路<br>
<a href="http://www.vcroad.com">http://www.vcroad.com</a></span></p>
<p><span><br>
<a href="http://www.vchelp.net">http://www.vchelp.net</a></span></p>
<p><span><br>
<br>
c维视点<br>
<a href="http://www.c-view.org/root/index.htm">http://www.c-view.org/root/index.htm</a><br>
最近发现的vc好站，书籍、软件、代码下载一应具全！！！<br>
<br>
<br>
游戏开发：<br>
风云工作室<br>
<a href="http://member.netease.com/~cloudwu/2000/index.html">http://member.netease.com/~cloudwu/2000/index.html</a><br>
标点游戏制作<br>
<a href="http://makegame.myetang.com/">http://makegame.myetang.com/</a><br>
未来开发者<br>
<a href="http://www.fdev.net/">http://www.fdev.net/</a><br>
<br>
综合的：<br>
中国软件网<br>
<a href="http://www.csdn.net">http://www.csdn.net</a></span></p>
<p><span href="http://www.itebook.net">http://www.itebook.net<br>
<br>
最后公布一个巨好的，狂多的电子书下载<br>
<a href="http://www.pdown.net">http://www.pdown.net</a><br>
还有巨好的<br>
<a href="http://www.codestudy.net/default.asp">http://www.codestudy.net/default.asp</a></span><span programming=""><br>
http://www.cj.idv.tw/<br>
华人wince论坛<br>
www.wince.com.tw<br>
美斯比论坛<br>
www.msptc.com/bbs<br>
移动技术网社区<br>
www.msale.net/bbs<br>
嵌入式研究网<br>
www.cnemb.com<br>
eMbedded Visual C++论坛 CN Dev Forum<br>
http://www.copathway.com/cndevforum/cndevforum.asp<br>
新闻组<br>
http://groups.google.com.tw/groups?hl=zh-TW&amp;lr=&amp;ie=UTF-8&amp;oe=UTF-8&amp;q=microsoft.public.windowsce.embedded.vc(EN)<br>
新闻组<br>
http://communities.microsoft.com/Newsgroups/default.asp?(EN)ICP=embedded&amp;sLCID=US&amp;newsgroup=microsoft.public.windowsce.embedded.vc(EN)<br>
Pocket PC Developer Network<br>
http://64.41.105.202/forum/(EN)<br>
http://www.codeproject.com/(EN)<br>
CE Programming<br>
http://www.codeguru.com/ce/index.shtml(EN)<br>
www.cegadgets.com(EN)<br>
windows embedded tech bulletin<br>
http://windowsembedded.com(EN)<br>
http://msdn.micro<br></span></p> ]]></description>
		<eb:creationDate>2009-03-04 17:18:56</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ VC中的消息传递机制 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/3983.html</link>
		<description><![CDATA[ <p><font size="2">摘要：Windows编程和Dos编程，一个很大的区别就是，Windows编程是事件驱动，消息传递的。所以，要学好Windows编程，必须对消息机制有一个清楚的认识，本文希望能够对消息的传递做一个全面的分析。首先让大家大致知道消息的传递方向，再解释消息传递机制。就以windows桌面（它也是窗体实例）为例，当我们单击开始按钮时，首先由鼠标驱动程序获得该消息，然后传给操作系统，操作系统并不知道是那个窗口的消息，所以它不能进行处理，这样它就将该消息传给应用程序（这里指桌面应用程序，其实就是线程，大伙可以打开任务管理器，看到有个进程是explorer.exe就是它了），然后由桌面应用程序将该消息加入自己的消息队列中，再通过Getmessage获得消息后判断是哪个窗口的消息（这个很简单，因为在消息结构中都有个窗口句柄成员变量hwnd），这样再有操作系统调用过程处理函数进行消息处理，显示开始菜单条，这样就完成一次消息处理了。下面将进一步详解：&nbsp;&nbsp;<br>
　　什么是消息？&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息系统对于一个win32程序来说十分重要，它是一个程序运行的动力源泉。一个消息，是系统定义的一个32位的值，他唯一的定义了一个事件，向Windows发出一个通知，告诉应用程序某个事情发生了。例如，单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息本身是作为一个记录传递给应用程序的，这个记录中包含了消息的类型以及其他信息。例如，对于单击鼠标所产生的消息来说，这个记录中包含了单击鼠标时的坐标。这个记录类型叫做MSG，MSG含有来自windows应用程序消息队列的消息信息，它在Windows中声明如下：&nbsp;&nbsp;&nbsp;<br>
<br>
typedef struct tagMsg&nbsp;&nbsp;&nbsp;<br>
{&nbsp;&nbsp;&nbsp;<br>
HWND hwnd; 接受该消息的窗口句柄&nbsp;&nbsp;&nbsp;<br>
UINT message; 消息常量标识符，也就是我们通常所说的消息号&nbsp;&nbsp;&nbsp;<br>
WPARAM wParam; 32位消息的特定附加信息，确切含义依赖于消息值 ，如果消息是WM_CHAR，则该值为字符的ASCI码值&nbsp;&nbsp;<br>
LPARAM lParam; 32位消息的特定附加信息，确切含义依赖于消息值&nbsp;&nbsp;&nbsp;<br>
DWORD time; 消息创建时的时间&nbsp;&nbsp;&nbsp;<br>
POINT pt; 消息创建时的鼠标/光标在屏幕坐标系中的位置&nbsp;&nbsp;&nbsp;<br>
}MSG;&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息可以由系统或者应用程序产生。系统在发生输入事件时产生消息。举个例子, 当用户敲键, 移动鼠标或者单击控件。系统也产生消息以响应由应用程序带来的变化, 比如应用程序改变系统字体改变窗体大小。应用程序可以产生消息使窗体执行任务，或者与其他应用程序中的窗口通讯。&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息中有什么？&nbsp;&nbsp;&nbsp;<br>
<br>
　　我给出了上面的注释，是不是会对消息结构有了一个比较清楚的认识？如果还没有，那么我们再试着给出下面的解释：&nbsp;&nbsp;&nbsp;<br>
<br>
　　hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象，因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。&nbsp;&nbsp;&nbsp;<br>
<br>
　　message用于区别其他消息的常量值，这些常量可以是Windows单元中预定义的常量，也可以是自定义的常量。消息标识符以常量命名的方式指出消息的含义。当窗口过程接收到消息之后，他就会使用消息标识符来决定如何处理消息。例如、WM_PAINT告诉窗口过程窗体客户区被改变了需要重绘。符号常量指定系统消息属于的类别，其前缀指明了处理解释消息的窗体的类型。&nbsp;&nbsp;&nbsp;<br>
<br>
　　wParam 通常是一个与消息有关的常量值，也可能是窗口或控件的句柄。&nbsp;&nbsp;&nbsp;<br>
<br>
　　lParam 通常是一个指向内存中数据的指针。由于WParam、lParam和Pointer都是32位的，因此，它们之间可以相互转换。&nbsp;&nbsp;&nbsp;<br>
<br>
消息标识符的值&nbsp;&nbsp;&nbsp;<br>
<br>
　　系统保留消息标识符的值在0x0000在0x03ff(WM_USER-1)范围。这些值被系统定义消息使用。 应用程序不能使用这些值给自己的消息。应用程序消息从WM_USER（0X0400）到0X7FFF，或0XC000到0XFFFF；WM_USER到0X7FFF范围的消息由应用程序自己使用；0XC000到0XFFFF范围的消息用来和其他应用程序通信，我们顺便说一下具有标志性的消息值：&nbsp;&nbsp;&nbsp;<br>
<br>
WM_NULL---0x0000 空消息。&nbsp;&nbsp;&nbsp;<br>
0x0001----0x0087 主要是窗口消息。&nbsp;&nbsp;&nbsp;<br>
0x00A0----0x00A9 非客户区消息&nbsp;&nbsp;&nbsp;<br>
0x0100----0x0108 键盘消息&nbsp;&nbsp;&nbsp;<br>
0x0111----0x0126 菜单消息&nbsp;&nbsp;&nbsp;<br>
0x0132----0x0138 颜色控制消息&nbsp;&nbsp;&nbsp;<br>
0x0200----0x020A 鼠标消息&nbsp;&nbsp;&nbsp;<br>
0x0211----0x0213 菜单循环消息&nbsp;&nbsp;&nbsp;<br>
0x0220----0x0230 多文档消息&nbsp;&nbsp;&nbsp;<br>
0x03E0----0x03E8 DDE消息&nbsp;&nbsp;&nbsp;<br>
0x0400 WM_USER&nbsp;&nbsp;&nbsp;<br>
0x8000 WM_APP&nbsp;&nbsp;&nbsp;<br>
0x0400----0x7FFF 应用程序自定义私有消息&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息有分类？&nbsp;&nbsp;&nbsp;<br>
<br>
　　其实，windows中的消息虽然很多，但是种类并不繁杂，大体上有3种：窗口消息、命令消息和控件通知消息。&nbsp;&nbsp;&nbsp;<br>
<br>
　　窗口消息大概是系统中最为常见的消息，它是指由操作系统和控制其他窗口的窗口所使用的消息。例如CreateWindow、DestroyWindow和MoveWindow等都会激发窗口消息，还有我们在上面谈到的单击鼠标所产生的消息也是一种窗口消息。&nbsp;&nbsp;&nbsp;<br>
<br>
　　命令消息，这是一种特殊的窗口消息，他用来处理从一个窗口发送到另一个窗口的用户请求，例如按下一个按钮，他就会向主窗口发送一个命令消息。&nbsp;&nbsp;&nbsp;<br>
<br>
　　控件通知消息，是指这样一种消息，一个窗口内的子控件发生了一些事情，需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框，以及Windows公共控件如树状视图、列表视图等。例如，单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。 她类似于命令消息，当用户与控件窗****互时，那么控件通知消息就会从控件窗口发送到它的主窗口。但是这种消息的存在并不是为了处理用户命令，而是为了让主窗口能够改变控件，例如加载、显示数据。例如按下一个按钮，他向父窗口发送的消息也可以看作是一个控件通知消息；单击鼠标所产生的消息可以由主窗口直接处理，然后交给控件窗口处理。&nbsp;&nbsp;&nbsp;<br>
<br>
　　其中窗口消息及控件通知消息主要由窗口类即直接或间接由CWND类派生类处理。相对窗口消息及控件通知消息而言，命令消息的处理对象范围就广得多，它不仅可以由窗口类处理，还可以由文档类，文档模板类及应用类所处理。&nbsp;&nbsp;&nbsp;<br>
<br>
　　由于控件通知消息很重要的，人们用的也比较多，但是具体的含义往往令初学者晕头转向，所以我决定把常见的几个列出来供大家参考：&nbsp;&nbsp;&nbsp;<br>
<br>
　　按扭控件&nbsp;&nbsp;&nbsp;<br>
<br>
BN_CLICKED 用户单击了按钮&nbsp;&nbsp;&nbsp;<br>
BN_DISABLE 按钮被禁止&nbsp;&nbsp;&nbsp;<br>
BN_DOUBLECLICKED 用户双击了按钮&nbsp;&nbsp;&nbsp;<br>
BN_HILITE 用/户加亮了按钮&nbsp;&nbsp;&nbsp;<br>
BN_PAINT 按钮应当重画&nbsp;&nbsp;&nbsp;<br>
BN_UNHILITE 加亮应当去掉&nbsp;&nbsp;&nbsp;<br>
<br>
　　组合框控件&nbsp;&nbsp;&nbsp;<br>
<br>
CBN_CLOSEUP 组合框的列表框被关闭&nbsp;&nbsp;&nbsp;<br>
CBN_DBLCLK 用户双击了一个字符串&nbsp;&nbsp;&nbsp;<br>
CBN_DROPDOWN 组合框的列表框被拉出&nbsp;&nbsp;&nbsp;<br>
CBN_EDITCHANGE 用户修改了编辑框中的文本&nbsp;&nbsp;&nbsp;<br>
CBN_EDITUPDATE 编辑框内的文本即将更新&nbsp;&nbsp;&nbsp;<br>
CBN_ERRSPACE 组合框内存不足&nbsp;&nbsp;&nbsp;<br>
CBN_KILLFOCUS 组合框失去输入焦点&nbsp;&nbsp;&nbsp;<br>
CBN_SELCHANGE 在组合框中选择了一项&nbsp;&nbsp;&nbsp;<br>
CBN_SELENDCANCEL 用户的选择应当被取消&nbsp;&nbsp;&nbsp;<br>
CBN_SELENDOK 用户的选择是合法的&nbsp;&nbsp;&nbsp;<br>
CBN_SETFOCUS 组合框获得输入焦点&nbsp;&nbsp;&nbsp;<br>
<br>
　　编辑框控件&nbsp;&nbsp;&nbsp;<br>
<br>
EN_CHANGE 编辑框中的文本己更新&nbsp;&nbsp;&nbsp;<br>
EN_ERRSPACE 编辑框内存不足&nbsp;&nbsp;&nbsp;<br>
EN_HSCROLL 用户点击了水平滚动条&nbsp;&nbsp;&nbsp;<br>
EN_KILLFOCUS 编辑框正在失去输入焦点&nbsp;&nbsp;&nbsp;<br>
EN_MAXTEXT 插入的内容被截断&nbsp;&nbsp;&nbsp;<br>
EN_SETFOCUS 编辑框获得输入焦点&nbsp;&nbsp;&nbsp;<br>
EN_UPDATE 编辑框中的文本将要更新&nbsp;&nbsp;&nbsp;<br>
EN_VSCROLL 用户点击了垂直滚动条消息含义&nbsp;&nbsp;&nbsp;<br>
<br>
　　列表框控件&nbsp;&nbsp;&nbsp;<br>
<br>
LBN_DBLCLK 用户双击了一项&nbsp;&nbsp;&nbsp;<br>
LBN_ERRSPACE 列表框内存不够&nbsp;&nbsp;&nbsp;<br>
LBN_KILLFOCUS 列表框正在失去输入焦点&nbsp;&nbsp;&nbsp;<br>
LBN_SELCANCEL 选择被取消&nbsp;&nbsp;&nbsp;<br>
LBN_SELCHANGE 选择了另一项&nbsp;&nbsp;&nbsp;<br>
LBN_SETFOCUS 列表框获得输入焦点&nbsp;&nbsp;&nbsp;<br>
<br>
队列消息和非队列消息&nbsp;&nbsp;&nbsp;<br>
<br>
　　从消息的发送途径来看，消息可以分成2种：队列消息和非队列消息。消息队列由可以分成系统消息队列和线程消息队列。系统消息队列由Windows维护，线程消息队列则由每个GUI线程自己进行维护，为避免给non-GUI现成创建消息队列，所有线程产生时并没有消息队列，仅当线程第一次调用GDI函数数系统给线程创建一个消息队列。队列消息送到系统消息队列，然后到线程消息队列；非队列消息直接送给目的窗口过程。&nbsp;&nbsp;&nbsp;<br>
<br>
　　对于队列消息，最常见的是鼠标和键盘触发的消息，例如WM_MOUSERMOVE,WM_CHAR等消息，还有一些其它的消息，例如：WM_PAINT、WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后，相应的鼠标或键盘驱动程序就会把这些事件转换成相应的消息，然后输送到系统消息队列，由Windows系统去进行处理。Windows系统则在适当的时机，从系统消息队列中取出一个消息，根据前面我们所说的MSG消息结构确定消息是要被送往那个窗口，然后把取出的消息送往创建窗口的线程的相应队列，下面的事情就该由线程消息队列操心了，Windows开始忙自己的事情去了。线程看到自己的消息队列中有消息，就从队列中取出来，通过操作系统发送到合适的窗口过程去处理。&nbsp;&nbsp;&nbsp;<br>
<br>
　　一般来讲，系统总是将消息Post在消息队列的末尾。这样保证窗口以先进先出的顺序接受消息。然而,WM_PAINT是一个例外，同一个窗口的多个 WM_PAINT被合并成一个 WM_PAINT 消息, 合并所有的无效区域到一个无效区域。合并WM_PAIN的目的是为了减少刷新窗口的次数。&nbsp;&nbsp;&nbsp;<br>
<br>
　　非队列消息将会绕过系统队列和消息队列，直接将消息发送到窗口过程，。系统发送非队列消息通知窗口，系统发送消息通知窗口。 例如,当用户激活一个窗口系统发送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。这些消息通知窗口它被激活了。非队列消息也可以由当应用程序调用系统函数产生。例如,当程序调用SetWindowPos系统发送WM_WINDOWPOSCHANGED消息。一些函数也发送非队列消息，例如下面我们要谈到的函数。</font></p>
<p><font size="2">消息的发送&nbsp;&nbsp;</font></p>
<p><font size="2">　　了解了上面的这些基础理论之后，我们就可以进行一下简单的消息发送与接收。&nbsp;&nbsp;</font></p>
<p><font size="2">　　把一个消息发送到窗口有3种方式：发送、寄送和广播。&nbsp;&nbsp;</font></p>
<p><font size="2">　　发送消息的函数有SendMessage、SendMessageCallback、SendNotifyMessage、SendMessageTimeout；寄送消息的函数主要有PostMessage、PostThreadMessage、PostQuitMessage；广播消息的函数我知道的只有BroadcastSystemMessage、BroadcastSystemMessageEx。&nbsp;&nbsp;</font></p>
<p><font size="2">　　SendMessage的原型如下：LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)，这个函数主要是向一个或多个窗口发送一条消息，一直等到消息被处理之后才会返回。不过需要注意的是，如果接收消息的窗口是同一个应用程序的一部分，那么这个窗口的窗口函数就被作为一个子程序马上被调用；如果接收消息的窗口是被另外的线程所创建的，那么窗口系统就切换到相应的线程并且调用相应的窗口函数，这条消息不会被放进目标应用程序队列中。函数的返回值是由接收消息的窗口的窗口函数返回，返回的值取决于被发送的消息。&nbsp;&nbsp;</font></p>
<p><font size="2">　　PostMessage的原型如下：BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)，该函数把一条消息放置到创建hWnd窗口的线程的消息队列中，该函数不等消息被处理就马上将控制返回。需要注意的是，如果hWnd参数为HWND_BROADCAST，那么，消息将被寄送给系统中的所有的重叠窗口和弹出窗口，但是子窗口不会收到该消息；如果hWnd参数为NULL，则该函数类似于将dwThreadID参数设置成当前线程的标志来调用PostThreadMEssage函数。&nbsp;&nbsp;</font></p>
<p><font size="2">　　从上面的这2个具有代表性的函数，我们可以看出消息的发送方式和寄送方式的区别所在：被发送的消息是否会被立即处理，函数是否立即返回。被发送的消息会被立即处理，处理完毕后函数才会返回；被寄送的消息不会被立即处理，他被放到一个先进先出的队列中，一直等到应用程序空线的时候才会被处理，不过函数放置消息后立即返回。&nbsp;&nbsp;</font></p>
<p><font size="2">　　实际上，发送消息到一个窗口处理过程和直接调用窗口处理过程之间并没有太大的区别，他们直接的唯一区别就在于你可以要求操作系统截获所有被发送的消息，但是不能够截获对窗口处理过程的直接调用。&nbsp;&nbsp;</font></p>
<p><font size="2">　　以寄送方式发送的消息通常是与用户输入事件相对应的，因为这些事件不是十分紧迫，可以进行缓慢的缓冲处理，例如鼠标、键盘消息会被寄送，而按钮等消息则会被发送。&nbsp;&nbsp;</font></p>
<p><font size="2">　　广播消息用得比较少，BroadcastSystemMessage函数原型如下：&nbsp;&nbsp;</font></p>
<p><font size="2">long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);&nbsp;&nbsp;</font></p>
<p><font size="2">　　该函数可以向指定的接收者发送一条消息，这些接收者可以是应用程序、可安装的驱动程序、网络驱动程序、系统级别的设备驱动消息和他们的任意组合。需要注意的是，如果dwFlags参数是BSF_QUERY并且至少一个接收者返回了BROADCAST_QUERY_DENY，则返回值为０，如果没有指定BSF_QUERY，则函数将消息发送给所有接收者，并且忽略其返回值。&nbsp;&nbsp;</font></p>
<p><font size="2"><br>
消息的接收&nbsp;&nbsp;</font></p>
<p>　　消息的接收主要有３个函数：GetMessage、PeekMessage、WaitMessage。&nbsp;&nbsp;</p>
<p>　　　GetMessage原型如下：BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);&nbsp;&nbsp;</p>
<p>　　该函数用来获取与hWnd参数所指定的窗口相关的且wMsgFilterMin和wMsgFilterMax参数所给出的消息值范围内的消息。需要注意的是，如果hWnd为NULL，则GetMessage获取属于调用该函数应用程序的任一窗口的消息，如果wMsgFilterMin和wMsgFilterMax都是０，则GetMessage就返回所有可得到的消息。函数获取之后将删除消息队列中的除WM_PAINT消息之外的其他消息，至于WM_PAINT则只有在其处理之后才被删除。&nbsp;&nbsp;</p>
<p>　　PeekMessage原型如下：BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg）；&nbsp;&nbsp;</p>
<p>　　该函数用于查看应用程序的消息队列，如果其中有消息就将其放入lpMsg所指的结构中，不过，与GetMessage不同的是，PeekMessage函数不会等到有消息放入队列时才返回。同样，如果hWnd为NULL，则PeekMessage获取属于调用该函数应用程序的任一窗口的消息，如果hWnd=-1，那么函数只返回把hWnd参数为NULL的PostAppMessage函数送去的消息。如果wMsgFilterMin和wMsgFilterMax都是０，则PeekMessage就返回所有可得到的消息。函数获取之后将删除消息队列中的除WM_PAINT消息之外的其他消息，至于WM_PAINT则只有在其处理之后才被删除。&nbsp;&nbsp;<br>
　　&nbsp;&nbsp;<br>
　　WaitMessage原型如下：BOOL VaitMessage();当一个应用程序无事可做时，该函数就将控制权交给另外的应用程序，同时将该应用程序挂起，直到一个新的消息被放入应用程序的队列之中才返回。&nbsp;&nbsp;</p>
<p>　　消息的处理&nbsp;&nbsp;</p>
<p>　　接下来我们谈一下消息的处理，首先我们来看一下VC中的消息泵：&nbsp;&nbsp;</p>
<p>　　while(GetMessage(&amp;msg, NULL, 0, 0))&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
if(!TranslateAccelerator(msg.hWnd, hAccelTable, &amp;msg))&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
TranslateMessage(&amp;msg);&nbsp;&nbsp;<br>
DispatchMessage(&amp;msg);&nbsp;&nbsp;<br>
}&nbsp;&nbsp;<br>
}&nbsp;&nbsp;</p>
<p>　　首先，GetMessage从进程的主线程的消息队列中获取一个消息并将它复制到MSG结构，如果队列中没有消息，则GetMessage函数将等待一个消息的到来以后才返回。 如果你将一个窗口句柄作为第二个参数传入GetMessage，那么只有指定窗口的的消息可以从队列中获得。GetMessage也可以从消息队列中过滤消息只接受消息队列中落在范围内的消息。这时候就要利用GetMessage／PeekMessage指定一个消息过滤器。这个过滤器是一个消息标识符的范围或者是一个窗体句柄，或者两者同时指定。当应用程序要查找一个后入消息队列的消息是很有用。WM_KEYFIRST 和 WM_KEYLAST 常量用于接受所有的键盘消息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用于接受所有的鼠标消息。&nbsp;&nbsp;</p>
<p>　　然后TranslateAccelerator判断该消息是不是一个按键消息并且是一个加速键消息，如果是，则该函数将把几个按键消息转换成一个加速键消息传递给窗口的回调函数。处理了加速键之后，函数TranslateMessage将把两个按键消息WM_KEYDOWN和WM_KEYUP转换成一个WM_CHAR，不过需要注意的是，消息WM_KEYDOWN,WM_KEYUP仍然将传递给窗口的回调函数。&nbsp;&nbsp;</p>
<p>　　处理完之后，DispatchMessage函数将把此消息发送给该消息指定的窗口中已设定的回调函数。如果消息是WM_QUIT，则GetMessage返回０，从而退出循环体。应用程序可以使用PostQuitMessage来结束自己的消息循环。通常在主窗口的WM_DESTROY消息中调用。&nbsp;&nbsp;</p>
<p>　　下面我们举一个常见的小例子来说明这个消息泵的运用：&nbsp;&nbsp;</p>
<p>　　if (:eekMessage(&amp;msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
if (msg.message == WM_KEYDOWN &amp;&amp; msg.wParam == VK_ESCAPE)．．．&nbsp;&nbsp;<br>
}&nbsp;&nbsp;</p>
<p>　　这里我们接受所有的键盘消息，所以就用WM_KEYFIRST 和 WM_KEYLAST作为参数。最后一个参数可以是PM_NOREMOVE 或者 PM_REMOVE，表示消息信息是否应该从消息队列中删除。&nbsp;&nbsp;</p>
<p>　　所以这段小代码就是判断是否按下了Esc键，如果是就进行处理.</p>
<p>窗口过程&nbsp;&nbsp;<br>
<br>
　　窗口过程是一个用于处理所有发送到这个窗口的消息的函数。任何一个窗口类都有一个窗口过程。同一个类的窗口使用同样的窗口过程来响应消息。 系统发送消息给窗口过程将消息数据作为参数传递给他，消息到来之后，按照消息类型排序进行处理，其中的参数则用来区分不同的消息，窗口过程使用参数产生合适行为。&nbsp;&nbsp;<br>
<br>
　　一个窗口过程不经常忽略消息，如果他不处理，它会将消息传回到执行默认的处理。窗口过程通过调用DefWindowProc来做这个处理。窗口过程必须return一个值作为它的消息处理结果。大多数窗口只处理小部分消息和将其他的通过DefWindowProc传递给系统做默认的处理。窗口过程被所有属于同一个类的窗口共享，能为不同的窗口处理消息。下面我们来看一下具体的实例：&nbsp;&nbsp;<br>
<br>
　　　LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)&nbsp;&nbsp;<br>
　　　{&nbsp;&nbsp;<br>
int wmId, wmEvent;&nbsp;&nbsp;<br>
PAINTSTRUCT ps;&nbsp;&nbsp;<br>
HDC hdc;&nbsp;&nbsp;<br>
TCHAR szHello[MAX_LOADSTRING];&nbsp;&nbsp;<br>
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);&nbsp;&nbsp;<br>
<br>
switch (message)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
case WM_COMMAND:&nbsp;&nbsp;<br>
wmId = LOWORD(wParam);&nbsp;&nbsp;<br>
wmEvent = HIWORD(wParam);&nbsp;&nbsp;<br>
// Parse the menu selections:&nbsp;&nbsp;<br>
switch (wmId)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
case IDM_ABOUT:&nbsp;&nbsp;<br>
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
case IDM_EXIT:&nbsp;&nbsp;<br>
DestroyWindow(hWnd);&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
default:&nbsp;&nbsp;<br>
return DefWindowProc(hWnd, message, wParam, lParam);&nbsp;&nbsp;<br>
}&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
case WM_PAINT:&nbsp;&nbsp;<br>
hdc = BeginPaint(hWnd, &amp;ps);&nbsp;&nbsp;<br>
// TODO: Add any drawing code here...&nbsp;&nbsp;<br>
RECT rt;&nbsp;&nbsp;<br>
GetClientRect(hWnd, &amp;rt);&nbsp;&nbsp;<br>
DrawText(hdc, szHello, strlen(szHello), &amp;rt, DT_CENTER);&nbsp;&nbsp;<br>
EndPaint(hWnd, &amp;ps);&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
case WM_DESTROY:&nbsp;&nbsp;<br>
PostQuitMessage(0);&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
default:&nbsp;&nbsp;<br>
return DefWindowProc(hWnd, message, wParam, lParam);&nbsp;&nbsp;<br>
　　　 }&nbsp;&nbsp;<br>
　　 return 0;&nbsp;&nbsp;<br>
　　　}&nbsp;&nbsp;<br>
<br>
　　消息分流器&nbsp;&nbsp;<br>
<br>
　　通常的窗口过程是通过一个switch语句来实现的，这个事情很烦，有没有更简便的方法呢？有，那就是消息分流器，利用消息分流器，我们可以把switch语句分成更小的函数，每一个消息都对应一个小函数，这样做的好处就是对消息更容易管理。&nbsp;&nbsp;<br>
<br>
　　之所以被称为消息分流器，就是因为它可以对任何消息进行分流。下面我们做一个函数就很清楚了：&nbsp;&nbsp;<br>
<br>
　　void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
switch(id)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
case ID_A:&nbsp;&nbsp;<br>
if(codeNotify==EN_CHANGE)...&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
case ID_B:&nbsp;&nbsp;<br>
if(codeNotify==BN_CLICKED)...&nbsp;&nbsp;<br>
break;&nbsp;&nbsp;<br>
....&nbsp;&nbsp;<br>
}&nbsp;&nbsp;<br>
}&nbsp;&nbsp;<br>
<br>
　　然后我们修改一下窗口过程：&nbsp;&nbsp;<br>
<br>
　　LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
switch(message)&nbsp;&nbsp;<br>
{&nbsp;&nbsp;<br>
HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);&nbsp;&nbsp;<br>
HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);&nbsp;&nbsp;<br>
default:&nbsp;&nbsp;<br>
return DefWindowProc(hWnd, message, wParam, lParam);&nbsp;&nbsp;<br>
　　　 }&nbsp;&nbsp;<br>
　　 return 0;&nbsp;&nbsp;<br>
　　　}&nbsp;&nbsp;<br>
<br>
　　在WindowsX.h中定义了如下的HANDLE_MSG宏：&nbsp;&nbsp;<br>
<br>
　　　#define HANDLE_MSG(hwnd,msg,fn) \&nbsp;&nbsp;<br>
switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));&nbsp;&nbsp;<br>
<br>
　　实际上，HANDLE_WM_XXXX都是宏，例如：HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);将被转换成如下定义：&nbsp;&nbsp;<br>
<br>
　　　#define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\&nbsp;&nbsp;<br>
((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);&nbsp;&nbsp;<br>
<br>
　　好了，事情到了这一步，应该一切都明朗了。&nbsp;&nbsp;<br>
<br>
　　不过，我们发现在windowsx.h里面还有一个宏：FORWARD_WM_XXXX，我们还是那WM_COMMAND为例，进行分析：&nbsp;&nbsp;<br>
<br>
　　　#define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \&nbsp;&nbsp;<br>
(void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))&nbsp;&nbsp;<br>
<br>
　　所以实际上，FORWARD_WM_XXXX将消息参数进行了重新构造，生成了wParam &amp;&amp; lParam，然后调用了我们定义的函数。</p>
<p>MFC消息的处理实现方式&nbsp;&nbsp;&nbsp;<br>
<br>
　　初看MFC中的各种消息，以及在头脑中根深蒂固的C++的影响，我们可能很自然的就会想到利用C++的三大特性之一：虚拟机制来实现消息的传递，但是经过分析，我们看到事情并不是想我们想象的那样，在MFC中消息是通过一种所谓的消息映射机制来处理的。&nbsp;&nbsp;&nbsp;<br>
<br>
　　为什么呢？在潘爱民老师翻译的《Visual C++技术内幕》（第4版）中给出了详细的原因说明，我再简要的说一遍。在CWnd类中大约有110个消息，还有其它的MFC的类呢，算起来消息太多了，在C++中对程序中用到的每一个派生类都要有一个vtable，每一个虚函数在vtable中都要占用一个4字节大小的入口地址，这样一来，对于每个特定类型的窗口或控件，应用程序都需要一个440KB大小的表来支持虚拟消息控件函数。&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果说上面的窗口或控件可以勉强实现的话，那么对于菜单命令消息及按钮命令消息呢？因为不同的应用程序有不同的菜单和按钮，我们怎么处理呢？在MFC库的这种消息映射系统就避免了使用大的vtable，并且能够在处理常规Windows消息的同时处理各种各样的应用程序的命令消息。&nbsp;&nbsp;&nbsp;<br>
<br>
　　说白了，MFC中的消息机制其实质是一张巨大的消息及其处理函数的一一对应表，然后加上分析处理这张表的应用框架内部的一些程序代码.这样就可以避免在SDK编程中用到的繁琐的CASE语句。&nbsp;&nbsp;&nbsp;<br>
<br>
　　MFC的消息映射的基类CCmdTarget&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果你想让你的控件能够进行消息映射，就必须从CCmdTarget类中派生。CCmdTarget类是MFC处理命令消息的基础、核心。MFC为该类设计了许多成员函数和一些成员数据，基本上是为了解决消息映射问题的，所有响应消息或事件的类都从它派生，例如：应用程序类、框架类、文档类、视图类和各种各样的控件类等等，还有很多。&nbsp;&nbsp;&nbsp;<br>
<br>
　　不过这个类里面有２个函数对消息映射非常重要，一个是静态成员函数DispatchCmdMsg，另一个是虚函数OnCmdMsg。&nbsp;&nbsp;&nbsp;<br>
<br>
　　DispatchCmdMsg专门供MFC内部使用，用来分发Windows消息。OnCmdMsg用来传递和发送消息、更新用户界面对象的状态。&nbsp;&nbsp;&nbsp;<br>
<br>
　　CCmdTarget对OnCmdMsg的默认实现：在当前命令目标(this所指)的类和基类的消息映射数组里搜索指定命令消息的消息处理函数。&nbsp;&nbsp;&nbsp;<br>
<br>
　　这里使用虚拟函数GetMessageMap得到命令目标类的消息映射入口数组_messageEntries，然后在数组里匹配命令消息ID相同、控制通知代码也相同的消息映射条目。其中GetMessageMap是虚拟函数，所以可以确认当前命令目标的确切类。&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果找到了一个匹配的消息映射条目，则使用DispachCmdMsg调用这个处理函数；&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果没有找到，则使用_GetBaseMessageMap得到基类的消息映射数组，查找，直到找到或搜寻了所有的基类（到CCmdTarget）为止；&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果最后没有找到，则返回FASLE。&nbsp;&nbsp;&nbsp;<br>
<br>
　　每个从CCmdTarget派生的命令目标类都可以覆盖OnCmdMsg，利用它来确定是否可以处理某条命令，如果不能，就通过调用下一命令目标的OnCmdMsg，把该命令送给下一个命令目标处理。通常，派生类覆盖OnCmdMsg时 ，要调用基类的被覆盖的OnCmdMsg。&nbsp;&nbsp;&nbsp;<br>
<br>
　　在MFC框架中，一些MFC命令目标类覆盖了OnCmdMsg，如框架窗口类覆盖了该函数，实现了MFC的标准命令消息发送路径。必要的话，应用程序也可以覆盖OnCmdMsg，改变一个或多个类中的发送规定，实现与标准框架发送规定不同的发送路径。例如，在以下情况可以作这样的处理：在要打断发送顺序的类中把命令传给一个非MFC默认对象；在新的非默认对象中或在可能要传出命令的命令目标中。&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息映射的内容&nbsp;&nbsp;&nbsp;<br>
<br>
　　通过ClassWizard为我们生成的代码，我们可以看到，消息映射基本上分为2大部分：&nbsp;&nbsp;&nbsp;<br>
<br>
　　在头文件(.h)中有一个宏DECLARE_MESSAGE_MAP()，他被放在了类的末尾，是一个public属性的；与之对应的是在实现部分（.cpp)增加了一章消息映射表，内容如下：&nbsp;&nbsp;&nbsp;<br>
<br>
BEGIN_MESSAGE_MAP(当前类, 当前类的基类)&nbsp;&nbsp;&nbsp;<br>
file://{{AFX_MSG_MAP(CMainFrame)&nbsp;&nbsp;&nbsp;<br>
<br>
　消息的入口项&nbsp;&nbsp;&nbsp;<br>
<br>
file://}}AFX_MSG_MAP&nbsp;&nbsp;&nbsp;<br>
END_MESSAGE_MAP()&nbsp;&nbsp;&nbsp;<br>
<br>
　　但是仅是这两项还远不足以完成一条消息，要是一个消息工作，必须有以下3个部分去协作：&nbsp;&nbsp;&nbsp;<br>
1.在类的定义中加入相应的函数声明；&nbsp;&nbsp;&nbsp;<br>
<br>
　 2.在类的消息映射表中加入相应的消息映射入口项；&nbsp;&nbsp;&nbsp;<br>
<br>
　 3.在类的实现中加入相应的函数体；&nbsp;&nbsp;&nbsp;<br>
<br>
　　消息的添加&nbsp;&nbsp;&nbsp;<br>
<br>
　　有了上面的这些只是作为基础，我们接下来就做我们最熟悉、最常用的工作：添加消息。MFC消息的添加主要有2种方法：自动/手动，我们就以这2种方法为例，说一下如何添加消息。&nbsp;&nbsp;&nbsp;<br>
<br>
　　1、利用Class Wizard实现自动添加&nbsp;&nbsp;&nbsp;<br>
<br>
　　在菜单中选择View--&gt;Class Wizard，也可以用单击鼠标右键，选择Class Wizard，同样可以激活Class Wizard。选择Message Map标签，从Class name组合框中选取我们想要添加消息的类。在Object IDs列表框中，选取类的名称。此时， Messages列表框显示该类的大多数(若不是全部的话)可重载成员函数和窗口消息。类重载显示在列表的上部，以实际虚构成员函数的大小写字母来表示。其他为窗口消息，以大写字母出现，描述了实际窗口所能响应的消息ID。选中我们向添加的消息，单击Add Function按钮，Class Wizard自动将该消息添加进来。&nbsp;&nbsp;&nbsp;<br>
<br>
　　有时候，我们想要添加的消息本应该出现在Message列表中，可是就是找不到，怎么办？不要着急，我们可以利用Class Wizard上Class Info标签以扩展消息列表。在该页中，找到Message Filter组合框，通过它可以改变首页中Messages列表框中的选项。这里，我们选择Window，从而显示所有的窗口消息，一把情况下，你想要添加的消息就可以在Message列表框中出现了，如果还没有，那就接着往下看：）&nbsp;&nbsp;&nbsp;<br>
<br>
　　2、手动地添加消息处理函数&nbsp;&nbsp;&nbsp;<br>
<br>
　　如果在Messages列表框中仍然看不到我们想要的消息，那么该消息可能是被系统忽略掉或者是你自己创建的，在这种情况下，就必须自己手工添加。根据我们前面所说的消息工作的3个部件，我们一一进行处理：&nbsp;&nbsp;&nbsp;<br>
　　&nbsp;&nbsp;&nbsp;<br>
　　1) 在类的. h文件中添加处理函数的声明，紧接在//}}AFX_MSG行之后加入声明，注意：一定要以afx_msg开头。&nbsp;&nbsp;&nbsp;<br>
<br>
　　通常，添加处理函数声明的最好的地方是源代码中Class Wizard维护的表下面，但是在它标记其领域的｛｛｝｝括弧外面。这些括弧中的任何东西都将会被Class Wizard销毁。&nbsp;&nbsp;&nbsp;<br>
<br>
　　2) 接着，在用户类的.cpp文件中找到//}}AFX_MSG_MAP行，紧接在它之后加入消息入口项。同样，也是放在{ {} }的外面&nbsp;&nbsp;&nbsp;<br>
<br>
　　3) 最后，在该文件中添加消息处理函数的实体。</p> ]]></description>
		<eb:creationDate>2009-03-02 16:43:06</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ windows平台下的多线程编程 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/3854.html</link>
		<description><![CDATA[ <div><br>
<br>
windows是一种多任务的操作系统，在windows的一个进程内包含一个或多个线程。32位windows环境下的win32 api提供了多线程应用程序开发所需要的接口函数，而利用ｖｃ中提供的标准ｃ库也可以开发多线程应用程序，相应的ｍｆｃ类库封装了多线程编程的类，用户在开发时可根据应用程序的需要和特点选择相应的工具。为了使大家能全面地了解windows多线程编程技术，本文将重点介绍win32 api和mfc两种方式下如何编制多线程程序。<br>
<br>
多线程编程在win32方式下和mfc类库支持下的原理是一致的，进程的主线程在任何需要的时候都可以创建新的线程。当线程执行完后，自动终止线程; 当进程结束后，所有的线程都终止。所有活动的线程共享进程的资源，因此，在编程时需要考虑在多个线程访问同一资源时产生冲突的问题。当一个线程正在访问某进程对象，而另一个线程要改变该对象，就可能会产生错误的结果，编程时要解决这个冲突。<br>
<br>
win32 api下的多线程编程<br>
<br>
win32 api是windows操作系统内核与应用程序之间的界面，它将内核提供的功能进行函数包装，应用程序通过调用相关函数而获得相应的系统功能。为了向应用程序提供多线程功能，win32 api函数集中提供了一些处理多线程程序的函数集。直接用win32 api进行程序设计具有很多优点: 基于win32的应用程序执行代码小，运行效率高，但是它要求程序员编写的代码较多，且需要管理所有系统提供给程序的资源。用win32 api直接编写程序要求程序员对windows系统内核有一定的了解，会占用程序员很多时间对系统资源进行管理，因而程序员的工作效率降低。<br>
<br>
1. 用win32函数创建和终止线程<br>
<br>
win32函数库中提供了操作多线程的函数，包括创建线程、终止线程、建立互斥区等。在应用程序的主线程或者其他活动线程中创建新的线程的函数如下：<br>
<br>
handle createthread(lpsecurity_attributes lpthreadattributes,dword dwstacksize,lpthread_start_routine lpstartaddress,lpvoid lpparameter,dword dwcreationflags,lpdword lpthreadid);<br>
<br>
如果创建成功则返回线程的句柄，否则返回null。创建了新的线程后，该线程就开始启动执行了。但如果在dwcreationflags中使用了create_suspended特性，那么线程并不马上执行，而是先挂起，等到调用resumethread后才开始启动线程，在这个过程中可以调用下面这个函数来设置线程的优先权：<br>
<br>
bool setthreadpriority(handle hthread,int npriority);<br>
<br>
当调用线程的函数返回后，线程自动终止。如果需要在线程的执行过程中终止则可调用函数：<br>
<br>
void exitthread(dword dwexitcode);<br>
<br>
如果在线程的外面终止线程，则可调用下面的函数：<br>
<br>
bool terminatethread(handle hthread,dword dwexitcode);<br>
<br>
但应注意: 该函数可能会引起系统不稳定，而且线程所占用的资源也不释放。因此，一般情况下，建议不要使用该函数。<br>
<br>
如果要终止的线程是进程内的最后一个线程，则线程被终止后相应的进程也应终止。<br>
<br>
2. 线程的同步<br>
<br>
在线程体内，如果该线程完全独立，与其他线程没有数据存取等资源操作上的冲突，则可按照通常单线程的方法进行编程。但是，在多线程处理时情况常常不是这样，线程之间经常要同时访问一些资源。由于对共享资源进行访问引起冲突是不可避免的，为了解决这种线程同步问题，win32 api提供了多种同步控制对象来帮助程序员解决共享资源访问冲突。在介绍这些同步对象之前先介绍一下等待函数，因为所有控制对象的访问控制都要用到这个函数。<br>
<br>
win32 api提供了一组能使线程阻塞其自身执行的等待函数。这些函数在其参数中的一个或多个同步对象产生了信号，或者超过规定的等待时间才会返回。在等待函数未返回时，线程处于等待状态，此时线程只消耗很少的cpu时间。使用等待函数既可以保证线程的同步，又可以提高程序的运行效率。最常用的等待函数是：<br>
<br>
dword waitforsingleobject(handle hhandle，dword dwmilliseconds);<br>
<br>
而函数waitformultipleobject可以用来同时监测多个同步对象，该函数的声明为：<br>
<br>
dword waitformultipleobject(dword ncount,const handle *lphandles,bool bwaitall,dword dwmilliseconds);<br>
<br>
（1）互斥体对象<br>
<br>
mutex对象的状态在它不被任何线程拥有时才有信号，而当它被拥有时则无信号。mutex对象很适合用来协调多个线程对共享资源的互斥访问。可按下列步骤使用该对象：<br>
<br>
首先，建立互斥体对象，得到句柄：<br>
<br>
handle createmutex();<br>
<br>
然后，在线程可能产生冲突的区域前（即访问共享资源之前）调用waitforsingleobject，将句柄传给函数，请求占用互斥对象：<br>
<br>
dwwaitresult = waitforsingleobject(hmutex,5000l);<br>
<br>
共享资源访问结束，释放对互斥体对象的占用：<br>
<br>
releasemutex(hmutex);<br>
<br>
互斥体对象在同一时刻只能被一个线程占用，当互斥体对象被一个线程占用时，若有另一线程想占用它，则必须等到前一线程释放后才能成功。<br>
<br>
（2）信号对象<br>
<br>
信号对象允许同时对多个线程共享资源进行访问，在创建对象时指定最大可同时访问的线程数。当一个线程申请访问成功后，信号对象中的计数器减一，调用releasesemaphore函数后，信号对象中的计数器加一。其中，计数器值大于或等于０，但小于或等于创建时指定的最大值。如果一个应用在创建一个信号对象时，将其计数器的初始值设为０，就阻塞了其他线程，保护了资源。等初始化完成后，调用releasesemaphore函数将其计数器增加至最大值，则可进行正常的存取访问。可按下列步骤使用该对象：<br>
<br>
首先，创建信号对象：<br>
<br>
handle createsemaphore();<br>
<br>
或者打开一个信号对象：<br>
<br>
handle opensemaphore();<br>
<br>
然后，在线程访问共享资源之前调用waitforsingleobject。<br>
<br>
共享资源访问完成后，应释放对信号对象的占用：<br>
<br>
releasesemaphore();<br>
<br>
（3）事件对象<br>
<br>
事件对象(event)是最简单的同步对象，它包括有信号和无信号两种状态。在线程访问某一资源之前，需要等待某一事件的发生，这时用事件对象最合适。例如：只有在通信端口缓冲区收到数据后，监视线程才被激活。<br>
<br>
事件对象是用createevent函数建立的。该函数可以指定事件对象的类和事件的初始状态。如果是手工重置事件，那么它总是保持有信号状态，直到用resetevent函数重置成无信号的事件。如果是自动重置事件，那么它的状态在单个等待线程释放后会自动变为无信号的。用setevent可以把事件对象设置成有信号状态。在建立事件时，可以为对象命名，这样其他进程中的线程可以用openevent函数打开指定名字的事件对象句柄。<br>
<br>
（4）排斥区对象<br>
<br>
在排斥区中异步执行时，它只能在同一进程的线程之间共享资源处理。虽然此时上面介绍的几种方法均可使用，但是，使用排斥区的方法则使同步管理的效率更高。<br>
<br>
使用时先定义一个critical_section结构的排斥区对象，在进程使用之前调用如下函数对对象进行初始化:<br>
<br>
void initializecriticalsection(lpcritical_section);<br>
<br>
当一个线程使用排斥区时，调用函数：entercriticalsection或者tryentercriticalsection;<br>
<br>
当要求占用、退出排斥区时，调用函数leavecriticalsection，释放对排斥区对象的占用，供其他线程使用。<br>
<br>
基于mfc的多线程编程<br>
<br>
mfc是微软的vc开发集成环境中提供给程序员的基础函数库，它用类库的方式将win32 api进行封装，以类的方式提供给开发者。由于其快速、简捷、功能强大等特点深受广大开发者喜爱。因此，建议使用mfc类库进行应用程序的开发。<br>
<br>
在vc++附带的mfc类库中，提供了对多线程编程的支持，基本原理与基于win32 api的设计一致，但由于mfc对同步对象做了封装，因此实现起来更加方便，避免了对象句柄管理上的烦琐工作。<br>
<br>
在mfc中，线程分为两种：工作线程和用户接口线程。工作线程与前面所述的线程一致，用户接口线程是一种能够接收用户的输入、处理事件和消息的线程。<br>
<br>
1. 工作线程<br>
<br>
工作线程编程较为简单，设计思路与前面所讲的基本一致: 一个基本函数代表了一个线程，创建并启动线程后，线程进入运行状态; 如果线程用到共享资源，则需要进行资源同步处理。这种方式创建线程并启动线程时可调用函数：<br>
<br>
cwinthread*afxbeginthread( afx_threadproc pfnthreadproc, lpvoid pparam,int npriority= thread_priority_normal,uint nstacksize =0,dword dwcreateflags=0, lpsecurity_attributes lpsecurityattrs = null);参数pfnthreadproc是线程执行体函数，函数原形为: uint threadfunction( lpvoid pparam)。<br>
<br>
参数pparam是传递给执行函数的参数；<br>
<br>
参数npriority是线程执行权限，可选值：<br>
<br>
thread_priority_normal、thread_priority_lowest、thread_priority_highest、thread_priority_idle。<br>
<br>
参数dwcreateflags是线程创建时的标志，可取值create_suspended，表示线程创建后处于挂起状态，调用resumethread函数后线程继续运行，或者取值“0”表示线程创建后处于运行状态。<br>
<br>
返回值是cwinthread类对象指针，它的成员变量m_hthread为线程句柄，在win32 api方式下对线程操作的函数参数都要求提供线程的句柄，所以当线程创建后可以使用所有win32 api函数对pwinthread-&gt;m_thread线程进行相关操作。<br>
<br>
注意：如果在一个类对象中创建和启动线程时，应将线程函数定义成类外的全局函数。<br>
<br>
2. 用户接口线程<br>
<br>
基于mfc的应用程序有一个应用对象，它是cwinapp派生类的对象，该对象代表了应用进程的主线程。当线程执行完并退出线程时，由于进程中没有其他线程存在，进程自动结束。类cｗinapp从cｗinthread派生出来，cｗinthread是用户接口线程的基本类。我们在编写用户接口线程时，需要从cｗinthread派生我们自己的线程类，classwizard可以帮助我们完成这个工作。<br>
<br>
先用classwizard派生一个新的类，设置基类为cwinthread。注意：类的declare_dyncreate和implement_dyncreate宏是必需的，因为创建线程时需要动态创建类的对象。根据需要可将初始化和结束代码分别放在类的initinstance和exitinstance函数中。如果需要创建窗口，则可在initinstance函数中完成。然后创建线程并启动线程。可以用两种方法来创建用户接口线程，mfc提供了两个版本的afxbeginthread函数，其中一个用于创建用户接口线程。第二种方法分为两步进行：首先，调用线程类的构造函数创建一个线程对象；其次，调用cwinthread::createthread函数来创建该线程。线程建立并启动后，在线程函数执行过程中一直有效。如果是线程对象，则在对象删除之前，先结束线程。cwinthread已经为我们完成了线程结束的工作。<br>
<br>
3. 线程同步<br>
<br>
前面我们介绍了win32 api提供的几种有关线程同步的对象，在mfc类库中对这几个对象进行了类封装，它们有一个共同的基类csyncobject，它们的对应关系为: semaphore对应csemaphore、mutex对应cmutex、event对应cevent、criticalsection对应ccriticalsection。另外，mfc对两个等待函数也进行了封装，即csinglelock和cmultilock。因四个对象用法相似，在这里就以cmutex为例进行说明：<br>
<br>
创建一个cmutex对象:<br>
<br>
cmutex mutex(false,null,null);<br>
<br>
或cmutex mutex;<br>
<br>
当各线程要访问共享资源时使用下面代码：<br>
<br>
csinglelock sl(&amp;mutex);<br>
<br>
sl.lock();<br>
<br>
if(sl.islocked())<br>
<br>
//对共享资源进行操作...<br>
<br>
sl.unlock();<br>
<br>
结束语<br>
<br>
如果用户的应用程序需要多个任务同时进行相应的处理，则使用多线程是较理想的选择。这里，提醒大家注意的是在多线程编程时要特别小心处理资源共享问题以及多线程调试问题。</div> ]]></description>
		<eb:creationDate>2009-02-03 16:52:06</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 深入剖析mfc中windows消息处理、运行机制 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/3853.html</link>
		<description><![CDATA[ <div><br>
本人对windows系统、mfc谈不上有深入的了解，但对mfc本身包装api的机制很有兴趣，特别是读了候老师的《深入浅出mfc》后，感觉到visual c++的application framework十分精制［不敢用“完美”一词］。在以前，我对sdi结构处理消息有一定的认识，但对于模式对话框的消息机制不了解，读了《深入》一书也没能得到解决，近日，通过在csdn上网友的帮助，和查阅msdn，自认为已经了解。一时兴起，写下这些文字，没有其它目的，只是希望让后来者少走弯路，也希望和我一样喜欢“钻牛角尖”的人共同讨论、学习。如果你是牛人，那么你现在要慎重考虑有没有充足的时间读这些幼稚文字［何出此言？请大家看一下：http://www.csdn.net/expert/topic/13/13451.xml的相关评论］。本文中有些“理论”是我自己胡乱猜测，还请大家指正.［文中内容有些不可避免的会和《深入》一书某些内容重复］。<br>
<br>
正文：<br>
<br>
windows程序和dos程序的主要不同点之一是：windows程序是以事件为驱动、消息机制为基础。如何理解？<br>
举了例子，当你click windows “开始”button时，为什么就会弹出一个菜单呢？<br>
当你单击鼠标左键时，操作系统中与mouse相关的驱动程序在第一时间内得到这个信号［lbuttondown］,然后它通知操作系统―――“嗨，鼠标左键被单击了！”，操作系统得到这一信号后，马上要判断――用户单击鼠标左键，这是针对哪个窗口呢？如何判断？这很简单！当前状态中，具有焦点的窗口［或控件］就是了［这里当然是“开始”button了］。然后操作系统马上向这个窗口发送一条消息到这个窗口所在进程的消息队列，消息内容应是消息本身的代号、附加参数、窗口句柄…等等了。那么，只有操作系统才有资格发送消息至某一窗口的消息队列吗？不然，其它程序也有资格。你可以在你的程序中调用：sendmessage 、postmessage。这样，被单击的窗口得到了一条由操作系统发送的包含click的消息，操作系统已经暂时不再管窗口的任何事，因为它还要忙于处理其它事务。你的程序得到一条消息后如何做呢？windows对于你在“开始”button上的单击事件做出如下反映：弹出一菜单。可是，得到消息到做出反映这一过程是如何实现的呢？这就是本文讨论的主要内容［当然只是针对mfc了］。<br>
我首先简要谈一下sdi，然后会花更多文字描述模式对话框。<br>
对于sdi窗口，你的应用程序类的initinstance()大约如下：<br>
bool cex06aapp::initinstance()<br>
{ ……………<br>
csingledoctemplate* pdoctemplate;<br>
pdoctemplate = new csingledoctemplate(<br>
idr_mainframe,<br>
runtime_class(cex06adoc),<br>
runtime_class(cmainframe), // main sdi frame window<br>
runtime_class(cex06aview));<br>
adddoctemplate(pdoctemplate);<br>
ccommandlineinfo cmdinfo;<br>
parsecommandline(cmdinfo);<br>
if (!processshellcommand(cmdinfo))<br>
return false;<br>
m_pmainwnd-&gt;showwindow(sw_show);<br>
m_pmainwnd-&gt;updatewindow();<br>
return true;<br>
}<br>
完成一些如动态生成相关文档、视，显示主框架窗口、处理参数行信息等工作。这些都是显示在你工程中的“明码”。我们现在把断点设置到return true;一句，跟入mfc源码中，看看到底mfc内部做了什么。<br>
程序进入src\winmain.cpp，下一个大动作应是：<br>
nreturncode = pthread-&gt;run();<br>
各位看官注意了，重点来了。f11进入<br>
int cwinapp::run()<br>
{<br>
if (m_pmainwnd == null &amp;&amp; afxolegetuserctrl())<br>
{<br>
// not launched /embedding or /automation, but has no main window!<br>
trace0("warning: m_pmainwnd is null in cwinapp::run - quitting application.\n");<br>
afxpostquitmessage(0);<br>
}<br>
return cwinthread::run();<br>
}<br>
再次f11进入：<br>
int cwinthread::run()<br>
{<br>
assert_valid(this);<br>
<br>
// for tracking the idle time state<br>
bool bidle = true;<br>
long lidlecount = 0;<br>
<br>
// acquire and dispatch messages until a wm_quit message is received.<br>
for (;;)<br>
{<br>
// phase1: check to see if we can do idle work<br>
while (bidle &amp;&amp;<br>
!::peekmessage(&amp;m_msgcur, null, null, null, pm_noremove))<br>
{<br>
// call onidle while in bidle state<br>
if (!onidle(lidlecount++))<br>
bidle = false; // assume "no idle" state<br>
}<br>
<br>
// phase2: pump messages while available<br>
do<br>
{<br>
// pump message, but quit on wm_quit<br>
if (!pumpmessage())<br>
return exitinstance();<br>
<br>
// reset "no idle" state after pumping "normal" message<br>
if (isidlemessage(&amp;m_msgcur))<br>
{<br>
bidle = true;<br>
lidlecount = 0;<br>
}<br>
<br>
} while (::peekmessage(&amp;m_msgcur, null, null, null, pm_noremove));<br>
}<br>
<br>
assert(false); // not reachable<br>
}<br>
<br>
bool cwinthread::isidlemessage(msg* pmsg)<br>
{<br>
// return false if the message just dispatched should _not_<br>
// cause onidle to be run. messages which do not usually<br>
// affect the state of the user interface and happen very<br>
// often are checked for.<br>
<br>
// redundant wm_mousemove and wm_ncmousemove<br>
if (pmsg-&gt;message == wm_mousemove || pmsg-&gt;message == wm_ncmousemove)<br>
{<br>
// mouse move at same position as last mouse move?<br>
if (m_ptcursorlast == pmsg-&gt;pt &amp;&amp; pmsg-&gt;message == m_nmsglast)<br>
return false;<br>
<br>
m_ptcursorlast = pmsg-&gt;pt; // remember for next time<br>
m_nmsglast = pmsg-&gt;message;<br>
return true;<br>
}<br>
<br>
// wm_paint and wm_systimer (caret blink)<br>
return pmsg-&gt;message != wm_paint &amp;&amp; pmsg-&gt;message != 0x0118;<br>
}<br>
这是sdi处理消息的中心机构，但请注意，它觉对不是核心！<br>
分析一下，在无限循环for内部又出现一个while循环<br>
while (bidle &amp;&amp;<br>
!::peekmessage(&amp;m_msgcur, null, null, null, pm_noremove))<br>
{<br>
// call onidle while in bidle state<br>
if (!onidle(lidlecount++))<br>
bidle = false; // assume "no idle" state<br>
}<br>
这段代码是当你程序进程的消息队列中没有消息时，会调用onidle做一些后备工作，<br>
临时对象在这里被删除。当然它是虚函数。其中的peekmessage，是查看消息队列，如果有消息返回true，如果没有消息返回false，这里指定pm_noremove，是指查看过后不移走消息队列中刚刚被查看到的消息，也就是说这里的peekmessage只起到一个检测作用，显然返回false时［即没有消息］，才会进入循环内部，执行onidle，当然了，你的onidle返回flase，会让程序不再执行onidle。你可能要问：<br>
当bidle=0或消息队例中有消息时，程序又执行到哪了呢？<br>
do<br>
{<br>
// pump message, but quit on wm_quit<br>
if (!pumpmessage())<br>
return exitinstance();<br>
<br>
// reset "no idle" state after pumping "normal" message<br>
if (isidlemessage(&amp;m_msgcur))<br>
{<br>
bidle = true;<br>
lidlecount = 0;<br>
}<br>
<br>
} while (::peekmessage(&amp;m_msgcur, null, null, null, pm_noremove));<br>
<br>
看啊，又进入一个循环！<br>
其中有个重要的函数，pumpmessage，内容如下：<br>
bool cwinthread::pumpmessage()<br>
{<br>
assert_valid(this);<br>
<br>
if (!::getmessage(&amp;m_msgcur, null, null, null))<br>
{<br>
#ifdef _debug<br>
if (afxtraceflags &amp; traceappmsg)<br>
trace0("cwinthread::pumpmessage - received wm_quit.\n");<br>
m_ndisablepumpcount++; // application must die<br>
// note: prevents calling message loop things in 'exitinstance'<br>
// will never be decremented<br>
#endif<br>
return false;<br>
}<br>
<br>
#ifdef _debug<br>
if (m_ndisablepumpcount != 0)<br>
{<br>
trace0("error: cwinthread::pumpmessage called when not permitted.\n");<br>
assert(false);<br>
}<br>
#endif<br>
<br>
#ifdef _debug<br>
if (afxtraceflags &amp; traceappmsg)<br>
_afxtracemsg(_t("pumpmessage"), &amp;m_msgcur);<br>
#endif<br>
<br>
// process this message<br>
<br>
if (m_msgcur.message != wm_kickidle &amp;&amp; !pretranslatemessage(&amp;m_msgcur))<br>
{<br>
::translatemessage(&amp;m_msgcur);<br>
::dispatchmessage(&amp;m_msgcur);<br>
}<br>
return true;<br>
}<br>
如你所想，这才是mfc消息处理的核心基地[也是我个人认为的]。<br>
getmessage不同于peekmessae,它是不得到消息不罢体，peekmessage如果发现消息队列中没有消息会返回0，而getmessage如果发现没有消息,等,直到有了消息，而且，getmessage不同于peekmessage,它会将消息移走［当然，peekmessage也可以做到这点］。我想当你读了这个函数后，你应明白pretranslatemessage函数的用法了吧［我比较喜欢在程序中充分利用这个函数］。<br>
::translatemessage(&amp;m_msgcur);<br>
::dispatchmessage(&amp;m_msgcur);<br>
将消息发送到窗口的处理函数［它是由窗口类指定的］，之后的动作一直到你的程序做出反映的过程，你可以在《深入》一书中得到完美的解释。我们还是通过reurn true;回到cwinthread::run()中的do{}while；循环。然后还是对idle的处理，即便刚才你的onidle返回了false,在这里你看到,你的程序还是有机会执行它的。然后又是利用peekmessage检测消息队列：<br>
如果有消息［这个消息不被移动的原因是因为它要为pumpmessage内的getmessage所利用。］再次进入pumpmessage［叫它“消息泵”吧］。<br>
如果没有消息，退出do循环，但它还在for内部，所以又执行第一个while循环。<br>
这是cwinthread::run的一个执行过程。<br>
不用担心退不出for(;;)如果你的消息队列中有一条wm_quit,会使getmessage返回0,然后pumpmessage返回0而run（）内部：<br>
if (!pumpmessage())<br>
return exitinstance();。<br>
<br>
sdi就说到这，下面我来谈一下模式对话框。我分2种情况讨论：<br>
一当你的工程以模式对话框为基础时［没父窗口，或为桌面］。<br>
与sdi不同处在于，在应用程序类的initinstance内部：<br>
bool ccomboboxapp::initinstance()<br>
{<br>
afxenablecontrolcontainer();<br>
// standard initialization<br>
// if you are not using these features and wish to reduce the size<br>
// of your final executable, you should remove from the following<br>
// the specific initialization routines you do not need.<br>
#ifdef _afxdll<br>
enable3dcontrols(); // call this when using mfc in a shared dll<br>
#else<br>
enable3dcontrolsstatic(); // call this when linking to mfc statically<br>
#endif<br>
this-&gt;m_ncmdshow = sw_hide;<br>
ccomboboxdlg dlg;<br>
m_pmainwnd = &amp;dlg;<br>
int nresponse = dlg.domodal();<br>
if (nresponse == idok)<br>
{<br>
// todo: place code here to handle when the dialog is<br>
// dismissed with ok<br>
}<br>
else if (nresponse == idcancel)<br>
{<br>
// todo: place code here to handle when the dialog is<br>
// dismissed with cancel<br>
}<br>
// since the dialog has been closed, return false so that we exit the<br>
// application, rather than start the application's message pump.<br>
return false;<br>
}<br>
<br>
int nresponse = dlg.domodal();一句使你的整个程序都在domodal（）内部进行。而且，你退出domal()时［你一定结束了你的对话框］，initinstance返回的是false，我们知道，这样，cwinthread::run是不会执行的。<br>
但对话框程序是在哪里进行消息处理的呢。<br>
原来，dlg.domodal()内部会调用cwinthread::runmodalloop,它起到的作用和run()是一样的[当然内部有细小差别,请参考msdn]!!!<br>
<br>
第二种情况,你是在sdi[或其它]程序中调用dlg.domodal() 产生了一模式对话框［有父窗口］.<br>
<br>
这又是如何运作的呢？<br>
建了这样一个工程做为例子。<br>
sdi，在view中处理lbuttondown:<br>
mydlg.domodal();<br>
mydlg内有按钮,以惫后用.<br>
<br>
没有显示模式对话框前,消息处理一直在cthread::run()中进行.<br>
你单击后,程序执行点进入domodal()内部的runmodalloop,这又是一个消息处理机制.<br>
不过domodal()中调用runmodalloop,前会disable掉它的父窗口.从runmodalloop中出来后,再 enable它.<br>
模式对话框和非模式对话框都是通过调用createdialogindirect()产生创建对话框.那它和非模式对话框区别是什么造成的呢?<br>
1 模式对话框将父窗口disable掉.<br>
我原以为被disable的窗口是不接收消息的.但后来我马上发现我是错的.但,为什么你对被disable的窗口进行keyborad,mouse动作时,窗口没反映呢,我想,这可能是操作系统从中搞的鬼.我在本文一开始,就写出操作系统向窗口发送消息的过程,我想当它发现目标窗口处理disabled状态时,不会将消息发送给它,但这不能说窗口不接收消息,其它程序[或它本身]发送给它的消息还是可以接收并处理的.<br>
2 模式对话框本身有消息处理机制 runmodalloop.<br>
<br>
对以上两点加以实验.<br>
我在我的刚才建的项目中的模式对话框中加上一个button,其中加入如下代码:<br>
onbutton1()<br>
{<br>
getparaent()-&gt;enablewindow(1);<br>
}<br>
单击,后我们发现,此时它已经不再表现为”模态”,我试着点击菜单,还是会作出正常反映.<br>
我想这此消息[对于父窗口的,如:菜单动作]的处理也应是在模式对话框中的runmodalloop中进行处理的吧[这点我不能确定].<br></div> ]]></description>
		<eb:creationDate>2009-02-03 16:50:45</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ vc编程中如何操作数据库中的图像字段 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/3852.html</link>
		<description><![CDATA[ 在vc进行数据库编程中对图像的处理一直是个难点，经常有朋友为如何向数据库中添加图像或从数据库中读取图像数据并显示处理等问题所困扰，目前关于vc数据库编程的图书不少，但很少有涉及图象问题的，本文针对这一现状，介绍了如何解决上述的问题，希望可以对朋友们有所帮助。<br>
<br>
　　 本文以acess97为例，采用odbc方式打开数据库photo，数据库photo的images表中含有一个image的图像字段，在刚打开时显示第一条记录。存取操作时关键是确定数据的长度，读数据操作时图像数据可以从记录集的图像字段对应的长二进制成员变量m_image的成员m_hdata得到，这个句柄变量存放分配给图像字段的数据，该对象的另一个成员变量m_dwdatalength为该字段的实际长度，在某些情况下，m_dwdatalength的值有可能小于m_hdata中的数据长度值。具体内容可以参考msnd。以下实现的部分关键代码。首先请看 cdbimages记录集的定义:<br>
<br>
cdbimages::cdbimages(cdatabase* pdb)<br>
: crecordset(pdb)<br>
{<br>
//{{afx_field_init(cdbimages)<br>
m_nfields = 2;//数据库中有两个字段<br>
//}}afx_field_init<br>
m_ndefaulttype = snapshot;//数据库以快照形式打开<br>
}<br>
cstring cdbimages::getdefaultconnect()<br>
{<br>
return _t("odbc;dsn=ms access database");//以odbc操作数据库<br>
}<br>
cstring cdbimages::getdefaultsql()<br>
{<br>
return _t("[images]");//默认的操作是连接到数据库中的images表<br>
}<br>
void cdbimages::dofieldexchange(cfieldexchange* pfx)<br>
{<br>
//{{afx_field_map(cdbimages)<br>
pfx-&gt;setfieldtype(cfieldexchange::outputcolumn);<br>
rfx_longbinary(pfx, _t("[image]"), m_image);//记录集中的成员对象和表中的ole字段采用长二进制交换。<br>
//}}afx_field_map<br>
}<br>
///////////////////////////////////////////////////////////<br>
//从数据库中显示图像数据<br>
cdatabase m_db;//定义的数据库全局变量<br>
cbitmap bitmap;//定义的图像类全局变量，用以存储图像数据<br>
void cimageview::onopendatebase()<br>
{<br>
m_db.open(null, //以odbc形式打开数据库<br>
false,<br>
false,<br>
"odbc;driver={<br>
microsof access driver (*.mdb)};dbq=photo.mdb");<br>
cdbimages dbimages(m_db);<br>
cstring strfilename ;// 用来存放临时文件名，以该临时文件存放读取的数据库的图像数据。<br>
i=1;//i为临时文件号<br>
strfilename.format("%s",i)<br>
dbimages.open();<br>
if (dbimages.iseof())<br>
afxmessagebox("unable to get image from db");<br>
else<br>
{<br>
char tmppath[_max_path+1];<br>
gettemppath(_max_path,tmppath);//得到临时文件的目录；<br>
strfilename.insert(0,tmppath);//生成临时文件名<br>
cfile outfile(strfilename,cfile::modecreate|cfile::modewrite);<br>
//向临时文件写数据，数据库中数据读操作时关键是知道数据的长度，这可以从记录集的图像字段对应的长二进制成员变量m_image的成员dwdatalength得到；<br>
lpstr buffer = (lpstr)globallock(dbimages.m_image.m_hdata);<br>
outfile.writehuge(buffer,dbimages.m_image.m_dwdatalength);<br>
globalunlock(dbimages.m_image.m_hdata);<br>
outfile.close();<br>
//定义图像句柄；<br>
hbitmap hbm = (hbitmap)::loadimage(null,<br>
strfilename,<br>
image_bitmap,<br>
0,<br>
0,<br>
lr_loadfromfile);<br>
<br>
if (bitmap.attach(hbm))//将图像句柄和cbitmap对象联系起来<br>
{<br>
bitmap bm;<br>
bitmap.getbitmap(&amp;bm);//获取图像尺寸<br>
bitmap.setbitmapdimension(bm.bmwidth,bm.bmheight);<br>
return;<br>
}<br>
invalidate（）；//重画屏幕<br>
}<br>
/////////////////////////////////////////////<br>
void cimageview::ondraw(cdc* pdc)//显示图像<br>
{<br>
cdc memdc;<br>
memdc.createcompatibledc(pdc);<br>
cbitmap* pimage = memdc.selectobject(bitmap);<br>
csize imagesize = bitmap.getbitmapdimension();<br>
pdc-&gt;bitblt(0,0,imagesize.cx,imagesize.cy,&amp;memdc,0,0,srccopy);<br>
memdc.selectobject(pimage);<br>
}<br>
//////////////////////////////////////////////////////<br>
//以下是向数据中添加图像记录<br>
void cimageview::onsavedatebase()<br>
{//打开图像文件<br>
static char based_code szfilter[] = "bitmap files (*.bmp)|*.bmp||";<br>
cdbimages dbimages(m_db);<br>
cfiledialog fd(true,null,null,0,szfilter,this);<br>
if (idok != fd.domodal())<br>
return;<br>
dbimages.open();//打开数据库<br>
dbimages.addnew();//添加新的记录<br>
cfile fileimage;<br>
cfilestatus filestatus;<br>
fileimage.open(fd.getpathname(), cfile::moderead);<br>
fileimage.getstatus(filestatus);//得到打开的图像文件的状态信息；<br>
dbimages.m_image.m_dwdatalength = filestatus.m_size;<br>
hglobal hglobal= globalalloc(gptr,filestatus.m_size);//申请存放图像数据的空间。<br>
dbimages.m_image.m_hdata = globallock(hglobal);//将该空间付给m_hdata成员；<br>
//向缓冲区读图像数据<br>
fileimage.readhuge(dbimages.m_image.m_hdata,filestatus.m_size);//向m_image读图像数据。<br>
dbimages.setfielddirty(&amp;dbimages.m_image);//标志数据库已经修改；<br>
dbimages.setfieldnull(&amp;dbimages.m_image,false);//设置记录为null；<br>
dbimages.update();//刷新数据库的记录<br>
globalunlock(hglobal);<br>
dbimages.close();<br>
<br>
}<br>
　　 上述代码在vc6.0，windows98下编译通过，运行正常，有兴趣的朋友可以稍加修改，将文中所述的功能添加到自己的应用程序当中去。<br> ]]></description>
		<eb:creationDate>2009-02-03 16:42:07</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
    <item>
		<title><![CDATA[ 爱因斯坦的问题 ]]></title>
		<link>http://blog.tom.com/kaijie_luo/article/3838.html</link>
		<description><![CDATA[ 谁在养鱼作为宠物？ 给出了如下线索
<div>有五个具有五种不同颜色的房间；每个房间裏分别住著一个不同国籍的人；每个人都在喝一种特定品牌的饮料，抽一特定品牌的香烟，养一特定的宠物；没有任意两个人在抽相同品牌的香烟，或喝相同品牌的饮料，或养相同的宠物。<br>
1.英国人住在红色的房子裏；<br>
2.瑞典人养狗作为宠物；<br>
3.丹麦人喝茶；<br>
4.绿房子紧挨著白房子，在白房子的左边；<br>
5.绿房子的主人喝咖啡；<br>
6.抽 Pall Mall 牌香烟的人养鸟；<br>
7.黄色房子裏的人抽 Dunhill 牌香烟；<br>
8.住在中间那个房子裏的人喝牛奶；<br>
9.挪威人住在第一个房子裏(最左边)；<br>
10.抽 Blends 香烟的人和养猫的人相邻；<br>
11.养马的人和抽 Dunhill 牌香烟的人相邻；<br>
12.抽 BlueMaster 牌香烟的人喝啤酒；<br>
13.德国人抽 Prince 牌香烟；<br>
14.挪威人和住蓝房子的人相邻；<br>
15.抽Blends 香烟的人和喝矿泉水的人相邻；</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>1.黄房子，挪威人，矿泉水，Dunhill香烟，养猫<br>
2.蓝房子，丹麦人，茶，Blends香烟，养马<br>
3.红房子，英国人，牛奶，Pallmall香烟，养鸟<br>
4.绿房子，德国人，咖啡，Prince香烟，养鱼<br>
5.白房子，瑞典人，啤酒，Bluemaster香烟，养狗</div> ]]></description>
		<eb:creationDate>2009-02-02 14:59:33</eb:creationDate>
		<eb:modificationDate></eb:modificationDate>
    </item>
</channel>
</rss>