彼岸网络
百度首页 | 百度空间
 
文章列表
 
2008年07月12日 星期六 下午 10:07
费米悖论:

1950年的一天,诺贝尔奖获得者、物理学家费米在和别人讨论飞碟及外星人的问题时,突然冒出一句:“他们都在哪儿呢?”这句看似简单的问话,就是著名的“费米悖论”。

“费米悖论”隐含的意思是,从理论上讲,人类能用100万年的时间飞往银河系的各个星球,那么,外星人只要比人类早进化100万年,现在就应该来到地球了。换言之,“费米悖论”表明了这样的逻辑悖理:A.外星人是存在的——科学推论可以证明,外星人的进化要远远早于人类,他们应该已经来到地球并存在于某处了;B.外星人是不存在的——迄今为止,人类并未发现任何有关外星人存在的蛛丝马迹。
“费米悖论”自成,在天文学界就有着相当的影响,因为它是基于科学探知的事实:古老的银河系,已有约100多亿年的年龄,而银河系的空间直径却只有大约10万光年,就是说,即使外星人仅以光速的千分之一翱翔太空,他们也不过只需1亿年左右的时间就可以横穿银河系——这个时间远远短于银河系的年龄。而且仅从数学概率上分析,在浩瀚的宇宙里,应该有着众多的类似地球的适合于生命存在的星体。并且这其中,有些星体的年龄要远远大于地球,因此,它们上面的生命进化,也要远远早于地球上的人类。
“费米悖论”生成几十年来,人类对太空的探索已有长足的进展。宇宙飞船已经参观或探测了太阳系中绝大部分的行星及其主要卫星,天文学家还追踪了成千上万颗星球发出的微波信号。但是,这些搜寻行动一无所获,人类并没有发现能够证明外星人存在的生命信号。“费米悖论”的实质就是否定外星文明的存在:既然我们至今还未发现外星人的蛛丝马迹,为什么还要相信它呢?

黑暗森林理论:

宇宙就是一座黑暗森林,每个文明都是带枪的猎人,像幽灵般潜行于林间,轻轻拨开挡路的树枝,竭力不让脚步发出一丁点声音,连呼吸都小心翼翼;他必须小心,因为林中到处有与他一样潜行的猎人。如果他发现了别的生命,能做的只有一件事:开枪消灭之。在这片森林中,他人就是地狱,就是永恒的威胁,任何暴露自己存在的生命都将很快被消灭。这就是宇宙文明的图景,这就是对费米悖论的解释。

 
2008年06月23日 星期一 上午 08:54

很多教学课件都是采用ppt插入flash的形式制作的,在ppt中插入flash影片有多种方法,现在使用较多的是采用控件方式插入,然后选择“嵌入影片”,这样一来,这个flash影片就保存在ppt文件的内部了,不用担心其链接路径出错的种种问题。
如何将ppt中嵌入的swf取出来?猛一看,这个问题倒很简单,因为过去想把doc文档中的图片取出,只要将doc另存为 html就可以了,那些图片文件就全面出现在该目录下的*.files文件夹中了。但是这一招用在swf上就不灵了,类似将网页“另存为”的操作,swf 文件是不会和图片一样,会自动保存下来。
经过多次试验,发现直接将这个flash影片复制到如doc、ppt之类的office文档,都是可行的,但是无法复制到网页文件中。如果直接复制 到资源管理器中,则形成一个文档片段文件。
经过几次测试,终于找到了这个片段文件中swf的头部和底部的标志了:头部标志为465753(FWS)(包含第一个字符),结束标志为3a5c(:\)(包含最后一个字符)。但是,3a4c标志将在片段文件中出现多次,我们要使用最后一次出现的位置,因为这是片段中关于Flash文件的路径的记录。使用十六进制工具winhex复制这一块,保存为一个新的文件,命名为*.swf,然后用flash播 放器打开就可以看到swf影片已经成功提取出来了。

同理对于DOC文档。

 
2008年06月07日 星期六 上午 08:29
Mcafee VirusScan Enterprise 8.0i/8.5i去除启动界面

8.0

打开路径为[HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\VirusScan Enterprise\CurrentVersion],双击右侧名为“bSkipSplash”的DWORD值,默认为0,我们将其值修改为1,表示假,也就是不显示启动画面。由于8.0没有禁止McAfee服务被停止的保护功能,所以随便你改拉,不会提示你注册表被锁定的拉。好了,不废话点击“确定”退出注册表吧,就算生效了。下次进入桌面你会发现红色的启动画面不在了,如果你有点怀念启动画面将原来的被修改成1的键值再修改为0便可。

===================

8.5I:

打开注册表路径到[HKEY_LOCAL_MACHINE\SOFTWARE\McAfee\DesktopProtection],右侧双击名为“bSkipSplash”的DWORD值,默认为0,我们将其值修改为1,表示假,也就是不显示启动画面。修改为1后我们点击“确定”保存,如果提示保存失败表示你的8.5锁定了注册表的写入。

 
2008年05月20日 星期二 下午 10:02

来自一个叫“海王牌”铅酸电池公司主页的说法,应该可以作为参考。

   海王牌铅酸电池一般使用期在23年,电动车电池保养的好坏,直接影响到电池的使用寿命,因此,消费者日常对电池的保养须做到以下几点:

1、电池无记忆效应,无须放电;

2、首次充电,应连续充电12小时;

3、建议每天行驶10公里左右,两天充电一次,20公里以上每天充电一次,夏天充电时间不超过8小时,冬天不超过10小时;

4、电池严禁长时间搁置不用也不充电,一般情况下,长时间搁置最好每半月补充一次 电;

5、养成在低速、爬坡和载物时,脚踏助力的好习惯。

6、电池使用到1年左右,应到海王电池销售点免费加液。

 
2008年05月10日 星期六 上午 08:32

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;

namespace cbytesGen
{
     /// <summary>
     /// Form1 的摘要说明。
     /// </summary>
     public class Form1 : System.Windows.Forms.Form
     {
          private System.Windows.Forms.Label label1;
          private System.Windows.Forms.Label label2;
          private System.Windows.Forms.Label label3;
          private System.Windows.Forms.Button button1;
          private System.Windows.Forms.Button button2;
          private System.Windows.Forms.TextBox txtInstrument;
          private System.Windows.Forms.TextBox txtCompany;
          private System.Windows.Forms.TextBox txtSerial;
          private System.Windows.Forms.StatusBar statusBar1;
          private System.Windows.Forms.StatusBarPanel statusBarPanel1;
          private System.Windows.Forms.StatusBarPanel statusBarPanel2;
          /// <summary>
          /// 必需的设计器变量。
          /// </summary>
          private System.ComponentModel.Container components = null;

          public Form1()
          {
               //
               // Windows 窗体设计器支持所必需的
               //
               InitializeComponent();

               //
               // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
               //
          }

          /// <summary>
          /// 清理所有正在使用的资源。
          /// </summary>
          protected override void Dispose( bool disposing )
          {
               if( disposing )
               {
                    if (components != null)
                    {
                         components.Dispose();
                    }
               }
               base.Dispose( disposing );
          }

          #region Windows 窗体设计器生成的代码
          /// <summary>
          /// 设计器支持所需的方法 - 不要使用代码编辑器修改
          /// 此方法的内容。
          /// </summary>
          private void InitializeComponent()
          {
               System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
               this.label1 = new System.Windows.Forms.Label();
               this.label2 = new System.Windows.Forms.Label();
               this.label3 = new System.Windows.Forms.Label();
               this.txtInstrument = new System.Windows.Forms.TextBox();
               this.txtCompany = new System.Windows.Forms.TextBox();
               this.txtSerial = new System.Windows.Forms.TextBox();
               this.button1 = new System.Windows.Forms.Button();
               this.button2 = new System.Windows.Forms.Button();
               this.statusBar1 = new System.Windows.Forms.StatusBar();
               this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
               this.statusBarPanel2 = new System.Windows.Forms.StatusBarPanel();
               ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
               ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).BeginInit();
               this.SuspendLayout();
               //
               // label1
               //
               this.label1.Location = new System.Drawing.Point(16, 16);
               this.label1.Name = "label1";
               this.label1.Size = new System.Drawing.Size(56, 23);
               this.label1.TabIndex = 0;
               this.label1.Text = "instrument";
               //
               // label2
               //
               this.label2.Location = new System.Drawing.Point(16, 40);
               this.label2.Name = "label2";
               this.label2.Size = new System.Drawing.Size(56, 23);
               this.label2.TabIndex = 1;
               this.label2.Text = "user";
               //
               // label3
               //
               this.label3.Location = new System.Drawing.Point(16, 64);
               this.label3.Name = "label3";
               this.label3.Size = new System.Drawing.Size(56, 23);
               this.label3.TabIndex = 2;
               this.label3.Text = "注册码";
               //
               // txtInstrument
               //
               this.txtInstrument.Location = new System.Drawing.Point(72, 12);
               this.txtInstrument.Name = "txtInstrument";
               this.txtInstrument.Size = new System.Drawing.Size(204, 21);
               this.txtInstrument.TabIndex = 3;
               this.txtInstrument.Text = "";
               //
               // txtCompany
               //
               this.txtCompany.Location = new System.Drawing.Point(72, 36);
               this.txtCompany.Name = "txtCompany";
               this.txtCompany.Size = new System.Drawing.Size(204, 21);
               this.txtCompany.TabIndex = 4;
               this.txtCompany.Text = "";
               //
               // txtSerial
               //
               this.txtSerial.Location = new System.Drawing.Point(72, 60);
               this.txtSerial.Name = "txtSerial";
               this.txtSerial.Size = new System.Drawing.Size(204, 21);
               this.txtSerial.TabIndex = 5;
               this.txtSerial.Text = "";
               //
               // button1
               //
               this.button1.Location = new System.Drawing.Point(44, 92);
               this.button1.Name = "button1";
               this.button1.TabIndex = 6;
               this.button1.Text = "确定";
               this.button1.Click += new System.EventHandler(this.button1_Click);
               //
               // button2
               //
               this.button2.Location = new System.Drawing.Point(176, 92);
               this.button2.Name = "button2";
               this.button2.TabIndex = 7;
               this.button2.Text = "取消";
               this.button2.Click += new System.EventHandler(this.button2_Click);
               //
               // statusBar1
               //
               this.statusBar1.Location = new System.Drawing.Point(0, 127);
               this.statusBar1.Name = "statusBar1";
               this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
                                                                                                               this.statusBarPanel1,
                                                                                                               this.statusBarPanel2});
               this.statusBar1.ShowPanels = true;
               this.statusBar1.Size = new System.Drawing.Size(292, 22);
               this.statusBar1.SizingGrip = false;
               this.statusBar1.TabIndex = 8;
               this.statusBar1.Text = "statusBar1";
               //
               // statusBarPanel1
               //
               this.statusBarPanel1.Alignment = System.Windows.Forms.HorizontalAlignment.Center;
               this.statusBarPanel1.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Contents;
               this.statusBarPanel1.Text = "syszt[OCN][BCG][CZG][DFCG][D.4s]";
               this.statusBarPanel1.Width = 212;
               //
               // statusBarPanel2
               //
               this.statusBarPanel2.Alignment = System.Windows.Forms.HorizontalAlignment.Center;
               this.statusBarPanel2.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
               this.statusBarPanel2.Text = "2005-11-5";
               this.statusBarPanel2.Width = 80;
               //
               // Form1
               //
               this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
               this.ClientSize = new System.Drawing.Size(292, 149);
               this.Controls.Add(this.statusBar1);
               this.Controls.Add(this.button2);
               this.Controls.Add(this.button1);
               this.Controls.Add(this.txtSerial);
               this.Controls.Add(this.txtCompany);
               this.Controls.Add(this.txtInstrument);
               this.Controls.Add(this.label3);
               this.Controls.Add(this.label2);
               this.Controls.Add(this.label1);
               this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
               this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
               this.MaximizeBox = false;
               this.Name = "Form1";
               this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
               this.Text = "ljb中文报告系统V1.25注册";
               ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
               ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).EndInit();
               this.ResumeLayout(false);

          }
          #endregion

          /// <summary>
          /// 应用程序的主入口点。
          /// </summary>
          [STAThread]
          static void Main()
          {
               Application.Run(new Form1());
          }

          private void button1_Click(object sender, System.EventArgs e)
          {
               string serial, str1;
               string key;
               int ebp;
               int esi;
               Encoding gb = Encoding.GetEncoding("gb2312");
              
               serial = "";
               ebp = 0;
               esi = 1;

               if (gb.GetBytes(txtCompany.Text).Length < 8)
               {
                    MessageBox.Show("公司名称至少有四个汉字或八个字母!","信息",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    txtCompany.Focus();
                    return;
               }
               key = txtCompany.Text.ToUpper() + txtInstrument.Text.ToUpper();
               if (gb.GetBytes(key).Length <12)
                    key = key + "123456789ABC";
              
               byte[] bytes = gb.GetBytes(key);

               for (int i = 0; i < bytes.Length; i++)
               {
                    ebp = ebp + bytes;
               }

               for (int i = 0; i < bytes.Length; i++)
               {
                    esi = esi * (ebp / bytes);
                    if (esi.ToString().Length > 10)
                         break;
               }
              
               esi = Math.Abs(esi + ebp);
               str1 = esi.ToString();
               for (int i = str1.Length - 1; i >= 0; i--)
               {
                    serial = serial + str1.Substring(i, 1);
               }

               serial = serial.Substring(0, 5) + "-" + serial.Substring(5, 5);
               txtSerial.Text = serial;

          }

          private void button2_Click(object sender, System.EventArgs e)
          {
               Application.Exit();
          }
     }
}

 
2008年04月22日 星期二 上午 10:16
1、360安全卫士在当前还不能算是杀毒软件,只能算是一个安全辅助工具。
2、360安全卫士在当前还算不错,但个人建议使用它的绿色免安装版(去霏凡软件园的绿色专栏里下载)。
3、360安全卫士的主要决策人之一叫周鸿祎,其人就是恶名着著的3721插件的作者,3721是恶意插件的最大的代表。不可否认周鸿祎其人的推广手段是前无古人、后无来者的,它干什么什么就出名。
4、在当前360安全卫士和最初的3721一样非常不错,但从其网站的内容不难看出其唯利味。以周鸿祎其人的人品,个人不看好360安全卫士,可以预见,将来的360会成为3721第二。
 
2007年12月29日 星期六 下午 09:05

从McAfee官方网站安安心心下载原汁原味的官方版本!超多正版

官方登录网页:https://secure.nai.com/apps/downloads/my_products/login.asp

Grant Number :1359034-NAI

Grant Number :1359037-NAI(被封)

(如遇号被封可改动数字1359034等试试)
输入1359125-NAI,可下载到企业版的杀毒(VirusScan Enterprise)和防火墙(Desktop Firewall)
输入1359155-NAI,可下载到反间谍模块(AntiSpyware).
墙有繁体中文的,反间谍有简体中文版
1359XXX-NAI

XXX换为任意数字均可登录,对应不同的产品组合

1359001-NAI 几乎全部企业版产品
1359125-NAI McAfee Desktop Firewall
1359155-NAI 可以下载防间谍软件

1326171-NET VirusScan Home Use Option


进去后找到以下软件,下载安装就可以了
McAfee VirusScan Enterprise 8.5 杀毒软件

还可以选择安装
McAfee AntiSpyware Enterprise Module 8.5 防间谍软件的软件
McAfee Desktop Firewall 防火墙软件

完全官方下载,包无病毒。
下载产品列表:
  McAfee Active VirusScan SMB Edition
  Desktop Server Security
  NetShield for Netware v4.62
  NetShield for Netware v4.63
  VirusScan Command Line Scanners
  VirusScan Enterprise v7.1.0
  VirusScan Enterprise v8.0i
  VirusScan Enterprise v8.5i
  VirusScan Multiplatform v4.5.1
  Management Solutions
  ePolicy Orchestrator Agent for NetWare
  ProtectionPilot 1.1
  ProtectionPilot 1.5   Messaging Web Security
  WebShield Appliance Upgrade Utility v2.6   Utilities
  Alert Manager v4.7.0
  Alert Manager v4.7.1
  AutoUpdate Architect v1.1.1
  AutoUpdate Architect v1.1.2
  CleanBoot 1.0 Service Pack 1
  Common Management Agent v3.5.5
  Common Management Agent v3.6.0
  Installation Designer v8.2
  Installation Designer v8.5
  PreScan V1.0


1326171-NET (Home Use软件)
1359034-NAI (企业版软件)

 
2007年11月18日 星期日 上午 08:43

C++ Builder 编写多线程下载程序

在当今的网络时代,下载软件是使用最为频繁的软件之一。几年来,下载技术也在不停地发展。最原始的下载功能仅仅是个“下载”过程,即从WEB服务器上连续地读取文件。其最大的问题是,由于网络的不稳定性,一旦连接断开使得下载过程中断,就不得不全部从头再来一次。
    随后,“断点续传”的概念就出来了,顾名思义,就是如果下载中断,在重新建立连接后,跳过已经下载的部分,而只下载还没有下载的部分。
无论“多线程下载”技术是否洪以容先生的发明,洪以容使得这项技术得到前所未有的关注是不争的事实。在“网络蚂蚁”软件流行开后,许多下载软件也都纷纷效仿,是否具?quot;多线程下载"技术、甚至能支持多少个下载线程都成了人们评测下载软件的要素。"多线程下载"的基础是WEB服务器支持远程的随机读取,也即支持"断点续传"。这样,在下载时可以把文件分成若干部分,每一部分创建一个下载线程进行下载。

    现在,不要说编写专门的下载软件,在自己编写的软件中,加入下载功能有时也非常必要。如让自己的软件支持自动在线升级,或者在软件中自动下载新的数据进行数据更新,这都是很有用、而且很实用的功能。本文的主题即怎样编写一个支持"断点续传"和"多线程"的下载模块。当然,下载的过程非常复杂,在一篇文章中难以全部阐明,所以,与下载过程关系不直接的部分基本上都忽略了,如异常处理和网络错误处理等,敬请各位读者注意。我使用的开发环境是C++ Builder 5.0,使用其他开发环境或者编程语言的朋友请自行作适当修改。

HTTP协议简介

    下载文件是电脑与WEB服务器交互的过程,它们交互的"语言"的专业名称是协议。传送文件的协议有多种,最常用的是HTTP(超文本传输协议)和FTP(文件传送协议),我采用的是HTTP。

    HTTP协议最基本的命令只有三条:Get、Post和Head。Get从WEB服务器请求一个特定的对象,比如HTML页面或者一个文件,WEB服务器通过一个Socket连接发送此对象作为响应;Head命令使服务器给出此对象的基本描述,比如对象的类型、大小和更新时间。Post命令用于向WEB服务器发送数据,通常使把信息发送给一个单独的应用程序,经处理生成动态的结果返回给浏览器。下载即是通过Get命令实现。

基本的下载过程

    编写下载程序,可以直接使用Socket函数,但是这要求开发人员理解、熟悉TCP/IP协议。为了简化Internet客户端软件的开发,Windows提供了一套WinInet API,对常用的网络协议进行了封装,把开发Internet软件的门槛大大降低了。我们需要使用的WinInet API函数如图1所示,调用顺序基本上是从上到下,其具体的函数原型请参考MSDN。

图1

    在使用这些函数时,必须严格区分它们使用的句柄。这些句柄的类型是一样的,都是HINTERNET,但是作用不同,这一点非常让人迷惑。按照这些句柄的产生顺序和调用关系,可以分为三个级别,下一级的句柄由上一级的句柄得到。

    InternetOpen是最先调用的函数,它返回的HINTERNET句柄级别最高,我习惯定义为hSession,即会话句柄。

    InternetConnect使用hSession句柄,返回的是http连接句柄,我把它定义为hConnect。

    HttpOpenRequest使用hConnect句柄,返回的句柄是http请求句柄,定义为hRequest。

    HttpSendRequest、HttpQueryInfo、InternetSetFilePointer和InternetReadFile都使用HttpOpenRequest返回的句柄,即hRequest。

    当这几个句柄不再使用是,应该用函数InternetCloseHandle把它关闭,以释放其占用的资源。

    首先建立一个名为THttpGetThread、创建后自动挂起的线程模块,我希望线程在完成后自动销毁,所以在构造函数中设置:

FreeOnTerminate = True; // 自动删除

    并增加以下成员变量:

char Buffer[HTTPGET_BUFFER_MAX+4]; // 数据缓冲区
AnsiString FURL; // 下载对象的URL
AnsiString FOutFileName; // 保存的路径和名称
HINTERNET FhSession; // 会话句柄
HINTERNET FhConnect; // http连接句柄
HINTERNET FhRequest; // http请求句柄
bool FSuccess; // 下载是否成功
int iFileHandle; // 输出文件的句柄

1、建立连接

    按照功能划分,下载过程可以分为4部分,即建立连接、读取待下载文件的信息并分析、下载文件和释放占用的资源。建立连接的函数如下,其中ParseURL的作用是从下载URL地址中取得主机名称和下载的文件的WEB路径,DoOnStatusText用于输出当前的状态:

//初始化下载环境
void THttpGetThread::StartHttpGet(void)
{
   AnsiString HostName,FileName;
   ParseURL(HostName, FileName);
   try
   {
      // 1.建立会话
      FhSession = InternetOpen("http-get-demo",
            INTERNET_OPEN_TYPE_PRECONFIG,
            NULL,NULL,
            0); // 同步方式
      if( FhSession==NULL)throw(Exception("Error:InterOpen"));
      DoOnStatusText("ok:InterOpen");
      // 2.建立连接
      FhConnect=InternetConnect(FhSession,
            HostName.c_str(),
            INTERNET_DEFAULT_HTTP_PORT,
            NULL,NULL,
            INTERNET_SERVICE_HTTP, 0, 0);
      if(FhConnect==NULL)throw(Exception("Error:InternetConnect"));
      DoOnStatusText("ok:InternetConnect");
      // 3.初始化下载请求
      const char *FAcceptTypes = "*/*";
      FhRequest = HttpOpenRequest(FhConnect,
            "GET", // 从服务器获取数据
            FileName.c_str(), // 想读取的文件的名称
            "HTTP/1.1", // 使用的协议
            NULL,
            &FAcceptTypes,
            INTERNET_FLAG_RELOAD,
            0);
      if( FhRequest==NULL)throw(Exception("Error:HttpOpenRequest"));
      DoOnStatusText("ok:HttpOpenRequest");
      // 4.发送下载请求
      HttpSendRequest(FhRequest, NULL, 0, NULL, 0);
      DoOnStatusText("ok:HttpSendRequest");
   }catch(Exception &exception)
   {
      EndHttpGet(); // 关闭连接,释放资源
      DoOnStatusText(exception.Message);
   }
}
// 从URL中提取主机名称和下载文件路径
void THttpGetThread::ParseURL(AnsiString &HostName,AnsiString &FileName)
{
   AnsiString URL=FURL;
   int i=URL.Pos("http://");
   if(i>0)
   {
      URL.Delete(1, 7);
   }
   i=URL.Pos("/");
   HostName = URL.SubString(1, i-1);
   FileName = URL.SubString(i, URL.Length());
}

    可以看到,程序按照图1中的顺序,依次调用InternetOpen、InternetConnect、HttpOpenRequest函数得到3个相关的句柄,然后通过HttpSendRequest函数把下载的请求发送给WEB服务器。

    InternetOpen的第一个参数是无关的,最后一个参数如果设置为INTERNET_FLAG_ASYNC,则将建立异步连接,这很有实际意义,考虑到本文的复杂程度,我没有采用。但是对于需要更高下载要求的读者,强烈建议采用异步方式。

    HttpOpenRequest打开一个请求句柄,命令是"GET",表示下载文件,使用的协议是"HTTP/1.1"。

    另外一个需要注意的地方是HttpOpenRequest的参数FAcceptTypes,表示可以打开的文件类型,我设置为"*/*"表示可以打开所有文件类型,可以根据实际需要改变它的值。

2、读取待下载的文件的信息并分析

    在发送请求后,可以使用HttpQueryInfo函数获取文件的有关信息,或者取得服务器的信息以及服务器支持的相关操作。对于下载程序,最常用的是传递HTTP_QUERY_CONTENT_LENGTH参数取得文件的大小,即文件包含的字节数。模块如下所示:

// 取得待下载文件的大小
int __fastcall THttpGetThread::GetWEBFileSize(void)
{
   try
   {
      DWORD BufLen=HTTPGET_BUFFER_MAX;
            DWORD dwIndex=0;
            bool RetQueryInfo=HttpQueryInfo(FhRequest,
            HTTP_QUERY_CONTENT_LENGTH,
            Buffer, &BufLen,
            &dwIndex);
      if( RetQueryInfo==false) throw(Exception("Error:HttpQueryInfo"));
      DoOnStatusText("ok:HttpQueryInfo");
      int FileSize=StrToInt(Buffer); // 文件大小
      DoOnGetFileSize(FileSize);
   }catch(Exception &exception)
   {
      DoOnStatusText(exception.Message);
   }
   return FileSize;
}

    模块中的DoOnGetFileSize是发出取得文件大小的事件。取得文件大小后,对于采用多线程的下载程序,可以按照这个值进行合适的文件分块,确定每个文件块的起点和大小。

3、下载文件的模块

    开始下载前,还应该先安排好怎样保存下载结果。方法很多,我直接采用了C++ Builder提供的文件函数打开一个文件句柄。当然,也可以采用Windows本身的API,对于小文件,全部缓冲到内存中也可以考虑。

// 打开输出文件,以保存下载的数据
DWORD THttpGetThread::OpenOutFile(void)
{
   try
   {
   if(FileExists(FOutFileName))
      DeleteFile(FOutFileName);
   iFileHandle=FileCreate(FOutFileName);
   if(iFileHandle==-1) throw(Exception("Error:FileCreate"));
   DoOnStatusText("ok:CreateFile");
   }catch(Exception &exception)
   {
      DoOnStatusText(exception.Message);
   }
   return 0;
}
// 执行下载过程
void THttpGetThread::DoHttpGet(void)
{
   DWORD dwCount=OpenOutFile();
   try
   {
      // 发出开始下载事件
      DoOnStatusText("StartGet:InternetReadFile");
      // 读取数据
      DWORD dwRequest; // 请求下载的字节数
      DWORD dwRead; // 实际读出的字节数
      dwRequest=HTTPGET_BUFFER_MAX;
      while(true)
      {
         Application->ProcessMessages();
         bool ReadReturn = InternetReadFile(FhRequest,
              (LPVOID)Buffer,
              dwRequest,
              &dwRead);
         if(!ReadReturn)break;
         if(dwRead==0)break;
         // 保存数据
         Buffer[dwRead]='\0';
         FileWrite(iFileHandle, Buffer, dwRead);
         dwCount = dwCount + dwRead;
         // 发出下载进程事件
         DoOnProgress(dwCount);
      }
      Fsuccess=true;
   }catch(Exception &exception)
   {
      Fsuccess=false;
      DoOnStatusText(exception.Message);
   }
   FileClose(iFileHandle);
   DoOnStatusText("End:InternetReadFile");
}

    下载过程并不复杂,与读取本地文件一样,执行一个简单的循环。当然,如此方便的编程还是得益于微软对网络协议的封装。

4、释放占用的资源

    这个过程很简单,按照产生各个句柄的相反的顺序调用InternetCloseHandle函数即可。

void THttpGetThread::EndHttpGet(void)
{
   if(FConnected)
   {
      DoOnStatusText("Closing:InternetConnect");
      try
      {
         InternetCloseHandle(FhRequest);
         InternetCloseHandle(FhConnect);
         InternetCloseHandle(FhSession);
      }catch(...){}
      FhSession=NULL;
      FhConnect=NULL;
      FhRequest=NULL;
      FConnected=false;
      DoOnStatusText("Closed:InternetConnect");
   }
}

    我觉得,在释放句柄后,把变量设置为NULL是一种良好的编程习惯。在这个示例中,还出于如果下载失败,重新进行下载时需要再次利用这些句柄变量的考虑。

5、功能模块的调用

    这些模块的调用可以安排在线程对象的Execute方法中,如下所示:

void __fastcall THttpGetThread::Execute()
{
   FrepeatCount=5;
   for(int i=0;i<FRepeatCount;i++)
   {
      StartHttpGet();
      GetWEBFileSize();
      DoHttpGet();
      EndHttpGet();
      if(FSuccess)break;
   }
   // 发出下载完成事件
   if(FSuccess)DoOnComplete();
   else DoOnError();
}

    这里执行了一个循环,即如果产生了错误自动重新进行下载,实际编程中,重复次数可以作为参数自行设置。

实现断点续传功能

    在基本下载的代码上实现断点续传功能并不是很复杂,主要的问题有两点:

1、 检查本地的下载信息,确定已经下载的字节数。所以应该对打开输出文件的函数作适当修改。我们可以建立一个辅助文件保存下载的信息,如已经下载的字节数等。我处理得较为简单,先检查输出文件是否存在,如果存在,再得到其大小,并以此作为已经下载的部分。由于Windows没有直接取得文件大小的API,我编写了GetFileSize函数用于取得文件大小。注意,与前面相同的代码被省略了。

DWORD THttpGetThread::OpenOutFile(void)
{
   ……
   if(FileExists(FOutFileName))
   {
      DWORD dwCount=GetFileSize(FOutFileName);
      if(dwCount>0)
      {
         iFileHandle=FileOpen(FOutFileName,fmOpenWrite);
         FileSeek(iFileHandle,0,2); // 移动文件指针到末尾
         if(iFileHandle==-1) throw(Exception("Error:FileCreate"));
         DoOnStatusText("ok:OpenFile");
         return dwCount;
      }
      DeleteFile(FOutFileName);
   }
   ……
}

2、 在开始下载文件(即执行InternetReadFile函数)之前,先调整WEB上的文件指针。这就要求WEB服务器支持随机读取文件的操作,有些服务器对此作了限制,所以应该判断这种可能性。对DoHttpGet模块的修改如下,同样省略了相同的代码:

void THttpGetThread::DoHttpGet(void)
{
   DWORD dwCount=OpenOutFile();
   if(dwCount>0) // 调整文件指针
   {
      dwStart = dwStart + dwCount;
      if(!SetFilePointer()) // 服务器不支持操作
      {
         // 清除输出文件
         FileSeek(iFileHandle,0,0); // 移动文件指针到头部
      }
   }
   ……
}

多线程下载

    要实现多线程下载,最主要的问题是下载线程的创建和管理,已经下载完成后文件的各个部分的准确合并,同时,下载线程也要作必要的修改。

1、下载线程的修改

    为了适应多线程程序,我在下载线程加入如下成员变量:

int FIndex; // 在线程数组中的索引
DWORD dwStart; // 下载开始的位置
DWORD dwTotal; // 需要下载的字节数
DWORD FGetBytes; // 下载的总字节数

    并加入如下属性值:

__property AnsiString URL = { read=FURL, write=FURL };
__property AnsiString OutFileName = { read=FOutFileName, write=FOutFileName};
__property bool Successed = { read=FSuccess};
__property int Index = { read=FIndex, write=FIndex};
__property DWORD StartPostion = { read=dwStart, write=dwStart};
__property DWORD GetBytes = { read=dwTotal, write=dwTotal};
__property TOnHttpCompelete OnComplete = { read=FOnComplete, write=FOnComplete };

    同时,在下载过程DoHttpGet中增加如下处理,

void THttpGetThread::DoHttpGet(void)
{
   ……
   try
   {
      ……
      while(true)
      {
         Application->ProcessMessages();
         // 修正需要下载的字节数,使得dwRequest + dwCount <dwTotal;
         if(dwTotal>0) // dwTotal=0表示下载到文件结束
         {
            if(dwRequest+dwCount>dwTotal)
            dwRequest=dwTotal-dwCount;
         }
         ……
         if(dwTotal>0) // dwTotal <=0表示下载到文件结束
         {
            if(dwCount>=dwTotal)break;
         }
      }
   }
   ……
   if(dwCount==dwTotal)FSuccess=true;
}

2、建立多线程下载组件

    我先建立了以TComponent为基类、名为THttpGetEx的组件模块,并增加以下成员变量:

// 内部变量
THttpGetThread **HttpThreads; // 保存建立的线程
AnsiString *OutTmpFiles; // 保存结果文件各个部分的临时文件
bool *FSuccesss; // 保存各个线程的下载结果
// 以下是属性变量
int FHttpThreadCount; // 使用的线程个数
AnsiString FURL;
AnsiString FOutFileName;

    各个变量的用途都如代码注释,其中的FSuccess的作用比较特别,下文会再加以详细解释。因为线程的运行具有不可逆性,而组件可能会连续地下载不同的文件,所以下载线程只能动态创建,使用后随即销毁。创建线程的模块如下,其中GetSystemTemp函数取得系统的临时文件夹,OnThreadComplete是线程下载完成后的事件,其代码在其后介绍:

// 分配资源
void THttpGetEx::AssignResource(void)
{
   FSuccesss=new bool[FHttpThreadCount];
   for(int i=0;i<FHttpThreadCount;i++)
      FSuccesss[i]=false;
   OutTmpFiles = new AnsiString[FHttpThreadCount];
   AnsiString ShortName=ExtractFileName(FOutFileName);
   AnsiString Path=GetSystemTemp();
   for(int i=0;i<FHttpThreadCount;i++)
      OutTmpFiles[i]=Path+ShortName+"-"+IntToStr(i)+".hpt";
   HttpThreads = new THttpGetThread *[FHttpThreadCount];
}
// 创建一个下载线程
THttpGetThread * THttpGetEx::CreateHttpThread(void)
{
   THttpGetThread *HttpThread=new THttpGetThread(this);
   HttpThread->URL=FURL;
   …… // 初始化事件
   HttpThread->OnComplete=OnThreadComplete; // 线程下载完成事件
   return HttpThread;
}
// 创建下载线程数组
void THttpGetEx::CreateHttpThreads(void)
{
   AssignResource();
   // 取得文件大小,以决定各个线程下载的起始位置
   THttpGetThread *HttpThread=CreateHttpThread();
   HttpThreads[FHttpThreadCount-1]=HttpThread;
   int FileSize=HttpThread->GetWEBFileSize();
   // 把文件分成FHttpThreadCount块
   int AvgSize=FileSize/FHttpThreadCount;
   int *Starts= new int[FHttpThreadCount];
   int *Bytes = new int[FHttpThreadCount];
   for(int i=0;i<FHttpThreadCount;i++)
   {
      Starts[i]=i*AvgSize;
      Bytes[i] =AvgSize;
   }
   // 修正最后一块的大小
   Bytes[FHttpThreadCount-1]=AvgSize+(FileSize-AvgSize*FHttpThreadCount);
   // 检查服务器是否支持断点续传
   HttpThread->StartPostion=Starts[FHttpThreadCount-1];
   HttpThread->GetBytes=Bytes[FHttpThreadCount-1];
   bool CanMulti=HttpThread->SetFilePointer();
   if(CanMulti==false) // 不支持,直接下载
   {
      FHttpThreadCount=1;
      HttpThread->StartPostion=0;
      HttpThread->GetBytes=FileSize;
      HttpThread->Index=0;
      HttpThread->OutFileName=OutTmpFiles[0];
   }else
   {
      HttpThread->OutFileName=OutTmpFiles[FHttpThreadCount-1];
      HttpThread->Index=FHttpThreadCount-1;
      // 支持断点续传,建立多个线程
      for(int i=0;i<FHttpThreadCount-1;i++)
      {
         HttpThread=CreateHttpThread();
         HttpThread->StartPostion=Starts[i];
         HttpThread->GetBytes=Bytes[i];
         HttpThread->OutFileName=OutTmpFiles[i];
         HttpThread->Index=i;
         HttpThreads[i]=HttpThread;
      }
   }
   // 删除临时变量
   delete Starts;
   delete Bytes;
}

    下载文件的下载的函数如下:

void __fastcall THttpGetEx::DownLoadFile(void)
{
   CreateHttpThreads();
   THttpGetThread *HttpThread;
   for(int i=0;i<FHttpThreadCount;i++)
   {
      HttpThread=HttpThreads[i];
      HttpThread->Resume();
   }
}

    线程下载完成后,会发出OnThreadComplete事件,在这个事件中判断是否所有下载线程都已经完成,如果是,则合并文件的各个部分。应该注意,这里有一个线程同步的问题,否则几个线程同时产生这个事件时,会互相冲突,结果也会混乱。同步的方法很多,我的方法是创建线程互斥对象。

const char *MutexToThread="http-get-thread-mutex";
void __fastcall THttpGetEx::OnThreadComplete(TObject *Sender, int Index)
{
   // 创建互斥对象
   HANDLE hMutex= CreateMutex(NULL,FALSE,MutexToThread);
   DWORD Err=GetLastError();
   if(Err==ERROR_ALREADY_EXISTS) // 已经存在,等待
   {
      WaitForSingleObject(hMutex,INFINITE);//8000L);
      hMutex= CreateMutex(NULL,FALSE,MutexToThread);
   }
   // 当一个线程结束时,检查是否全部认为完成
   FSuccesss[Index]=true;
   bool S=true;
   for(int i=0;i<FHttpThreadCount;i++)
   {
      S = S && FSuccesss[i];
   }
   ReleaseMutex(hMutex);
   if(S)// 下载完成,合并文件的各个部分
   {
      // 1. 复制第一部分
      CopyFile(OutTmpFiles[0].c_str(),FOutFileName.c_str(),false);
      // 添加其他部分
      int hD=FileOpen(FOutFileName,fmOpenWrite);
      FileSeek(hD,0,2); // 移动文件指针到末尾
      if(hD==-1)
      {
         DoOnError();
         return;
      }
      const int BufSize=1024*4;
      char Buf[BufSize+4];
      int Reads;
      for(int i=1;i<FHttpThreadCount;i++)
      {
         int hS=FileOpen(OutTmpFiles[i],fmOpenRead);
         // 复制数据
         Reads=FileRead(hS,(void *)Buf,BufSize);
         while(Reads>0)
         {
            FileWrite(hD,(void *)Buf,Reads);
            Reads=FileRead(hS,(void *)Buf,BufSize);
         }
         FileClose(hS);
      }
      FileClose(hD);
   }
}

结语

    到此,多线程下载的关键部分就介绍完了。但是在实际应用时,还有许多应该考虑的因素,如网络速度、断线等等都是必须考虑的。当然还有一些细节上的考虑,但是限于篇幅,就难以一一写明了。如果读者朋友能够参照本文编写出自己满意的下载程序,我也就非常欣慰了。我也非常希望读者能由此与我互相学习,共同进步。

    关于本文的详细示例(包括下载组件和使用程序),请到《程序员》网址下载。

 
2007年10月25日 星期四 上午 10:40

李白《将进酒》鉴赏



将进酒
李白
君不见黄河之水天上来,奔流到海不复回。
君不见高堂明镜悲白发,朝如青丝暮成雪。
人生得意须尽欢,莫使金樽空对月。
天生我材必有用,千金散尽还复来。
烹羊宰牛且为乐,会须一饮三百杯。
岑夫子,丹丘生,将进酒,杯莫停。
与君歌一曲,请君为我倾耳听。
钟鼓馔玉不足贵,但愿长醉不复醒。
古来圣贤皆寂寞,惟有饮者留其名。
陈王昔时宴平乐,斗酒十千恣欢谑。
主人何为言少钱,径须沽取对君酌。
五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。

李白咏酒的诗篇极能表现他的个性,这类诗固然数长安放还以后所作思想内容更为深沉,艺术表现更为成熟。《将进酒》即其代表作。

《将进酒》原是汉乐府短箫铙歌的曲调,题目意绎即“劝酒歌”,故古词有“将进酒,乘大白”云。作者这首“填之以申己意”(萧士赟《分类补注李太白诗》)的名篇,约作于天宝十一载(752),他当时与友人岑勋在嵩山另一好友元丹丘的颍阳山居为客,三人尝登高饮宴(《酬岑勋见寻就元丹丘对酒相待以诗见招》:“不以千里遥,命驾来相招。中逢元丹丘,登岭宴碧霄。对酒忽思我,长啸临清飙。”)。人生快事莫若置酒会友,作者又正值“抱用世之才而不遇合”(萧士赟)之际,于是满腔不合时宜借酒兴诗情,来了一次淋漓尽致的发抒。

诗篇发端就是两组排比长句,如挟天风海雨向读者迎面扑来。“君不见黄河之水天上来,奔流到海不复回”,颍阳去黄河不远,登高纵目,故借以起兴。黄河源远流长,落差极大,如从天而降,一泻千里,东走大海。如此壮浪景象,定非肉眼可以穷极,作者是想落天外,“自道所得”,语带夸张。上句写大河之来,势不可挡;下句写大河之去,势不可回。一涨一消,形成舒卷往复的咏叹味,是短促的单句(如“黄河落天走东海”)所没有的。紧接着,“君不见高堂明镜悲白发,朝如青丝暮成雪”,恰似一波未平、一波又起。如果说前二句为空间范畴的夸张,这二句则是时间范畴的夸张。悲叹人生短促,而不直言自伤老大,却说“高堂明镜悲白发”,一种搔首顾影、徒呼奈何的情态宛如画出。将人生由青春至衰老的全过程说成“朝”“暮”间事,把本来短暂的说得更短暂,与前两句把本来壮浪的说得更壮浪,是“反向”的夸张。于是,开篇的这组排比长句既有比意——以河水一去不返喻人生易逝,又有反衬作用——以黄河的伟大永恒形出生命的渺小脆弱。这个开端可谓悲感已极,却不堕纤弱,可说是巨人式的感伤,具有惊心动魄的艺术力量,同时也是由长句排比开篇的气势感造成的。这种开篇的手法作者常用,他如“弃我去者,咋日之日不可留;乱我心者,今日之日多烦忧”(《宣城谢朓楼饯别校书叔云》),沈德潜说:“此种格调,太白从心化出”,可见其颇具创造性。此诗两作“君不见”的呼告(一般乐府诗只于篇首或篇末偶一用之),又使诗句感情色彩大大增强。诗有所谓大开大阖者,此可谓大开。

“夫天地者,万物之逆旅也;光阴者,百代之过客也”(《春夜宴从弟桃李园序》),悲感虽然不免,但悲观却非李白性分之所近。在他看来,只要“人生得意”便无所遗憾,当纵情欢乐。五六两句便是一个逆转,由“悲”而翻作“欢”“乐”。从此直到“杯莫停”,诗情渐趋狂放。“人生达命岂暇愁,且饮美酒登高楼”(《梁园吟》),行乐不可无酒,这就入题。但句中未直写杯中之物,而用“金樽”“对月”的形象语言出之,不特生动,更将饮酒诗意化了;未直写应该痛饮狂欢,而以“莫使”“空”的双重否定句式代替直陈,语气更为强调。“人生得意须尽欢”,这似乎是宣扬及时行乐的思想,然而只不过是现象而已。诗人“得意”过没有?“凤凰初下紫泥诏,谒帝称觞登御筵”(《玉壶吟》)——似乎得意过;然而那不过是一场幻影,“弹剑作歌奏苦声,曳裾王门不称情”——又似乎并没有得意,有的是失望与愤慨。但就此消沉么?否。诗人于是用乐观好强的口吻肯定人生,肯定自我:“天生我材必有用”,这是一个令人击节赞叹的句子。“有用”而“必”,一何自信!简直象是人的价值宣言,而这个人——“我”——是须大写的。于此,从貌似消极的现象中露出了深藏其内的一种怀才不遇而又渴望用世的积极的本质内容来。正是“长风破浪会有时”,为什么不为这样的未来痛饮高歌呢!破费又算得了什么——“千金散尽还复来!”这又是一个高度自信的惊人之句,能驱使金钱而不为金钱所使,真足令一切凡夫俗子们咋舌。诗如其人,想诗人“曩者游维扬,不逾一年,散金三十余万”(《上安州裴长史书》),是何等豪举。故此句深蕴在骨子里的豪情,绝非装腔作势者可得其万一。与此气派相当,作者描绘了一场盛筵,那决不是“菜要一碟乎,两碟乎?酒要一壶乎,两壶乎?”而是整头整头地“烹羊宰牛”,不喝上“三百杯”决不甘休。

 
2007年09月05日 星期三 下午 10:25

旧“三字经 ” 全文:

人之初,性本善。性相近,习相远。苟不教,性乃迁。教之道,贵以专。

昔孟母,择邻处。子不学,断机杼。窦燕山,有义方。教五子,名俱扬。

养不教,父之过。教不严,师之惰。子不学,非所宜。幼不学,老何为。

玉不琢,不成器。人不学,不知义。为人子,方少时。亲师友,习礼仪。

香九龄,能温席。孝于亲,所当执。融四岁,能让梨。弟于长,宜先知。

首孝弟,次见闻。知某数,识某文。一而十,十而百。百而千,千而万。

三才者,天地人。三光者,日月星。三纲者,君臣义。父子亲,夫妇顺。

曰春夏,曰秋冬。此四时,运不穷。曰南北,曰西东。此四方,应乎中。

曰水火,木金土。此五行,本乎数。曰仁义,礼智信。此五常,不容紊。

稻粱菽,麦黍稷。此六谷,人所食。马牛羊,鸡犬豕。此六畜,人所饲。

曰喜怒,曰哀惧。爱恶欲,七情具。□土革,木石金。与丝竹,乃八音。

高曾祖,父而身。身而子,子而孙。自子孙,至元曾。乃九族,而之伦。

父子恩,夫妇从。兄则友,弟则恭。长幼序,友与朋。君则敬,臣则忠。

此十义,人所同。

凡训蒙,须讲究。详训诂,名句读。为学者,必有初。小学终,至四书。

论语者,二十篇。群弟子,记善言。孟子者,七篇止。讲道德,说仁义。

作中庸,子思笔。中不偏,庸不易。作大学,乃曾子。自修齐,至平治。

孝经通,四书熟。如六经,始可读。诗书易,礼春秋。号六经,当讲求。

有连山,有归藏。有周易,三易详。有典谟,有训诰。有誓命,书之奥。

我周公,作周礼。著六官,存治体。大小戴,注礼记。述圣言,礼乐备。

曰国风,曰雅颂。号四诗,当讽咏。诗既亡,春秋作。寓褒贬,别善恶。

三传者,有公羊。有左氏,有彀梁。经既明,方读子。撮其要,记其事。

五子者,有荀杨。文中子,及老庄。

经子通,读诸史。考世系,知终始。自羲农,至黄帝。号三皇,居上世。

唐有虞,号二帝。相揖逊,称盛世。夏有禹,商有汤。周文王,称三王。

夏传子,家天下。四百载,迁夏社。汤伐夏,国号商。六百载,至纣亡。

周武王,始诛纣。八百载,最长久。周辙东,王纲堕。逞干戈,尚游说。

始春秋,终战国。五霸强,七雄出。嬴秦氏,始兼并。传二世,楚汉争。

高祖兴,汉业建。至孝平,王莽篡。光武兴,为东汉。四百年,终于献。

魏蜀吴,争汉鼎。号三国,迄两晋。宋齐继,梁陈承。为南朝,都金陵。

北元魏,分东西。宇文周,兴高齐。迨至隋,一土宇。不再传,失统绪。

唐高祖,起义师。除隋乱,创国基。二十传,三百载。梁义之,国乃改。

炎宋兴,受周禅。十八传,南北混。辽于金,皆称帝。太祖兴,国大明。

号洪武,都金陵。迨成祖,迁燕京。十六世,至崇祯。阉乱后,寇内讧。

闯逆变,神器终。清顺治,据神京。至十传,宣统逊。举总统,共和成。

复汉土,民国兴。

廿二史,全在兹。载治乱,知兴衰。读史书,考实录。通古今,若亲目。

口而诵,心而惟。朝于斯,夕于斯。昔仲尼,师项□。古圣贤,尚勤学。

赵中令,读鲁论。彼既仕,学且勤。披蒲编,削竹简。彼无书,且知勉。

头悬梁,锥刺股。彼不教,自勤苦。如囊萤,如映雪。家虽贫,学不缀。

如负薪,如挂角。身虽劳,犹苦卓。苏老泉,二十七。始发愤,读书籍。

彼既老,犹悔迟。尔小生,宜早思。若梁□,八十二。对大廷,魁多士。

彼既成,众称异。尔小生,宜立志。莹八岁,能咏诗。泌七岁,能赋□。

彼颖悟,人称奇。尔幼学,当效之。蔡文姬,能辨琴。谢道□,能咏吟。

彼女子,且聪敏。尔男子,当自警。唐刘晏,方七岁。举神童,作正字。

彼虽幼,身己仕。尔幼学,勉而致。有为者,亦若是。

犬守夜,鸡司晨。苟不学,曷为人。蚕吐丝,蜂酿蜜。人不学,不如物。

幼而学,壮而行。上致君,下泽民。扬名声,显父母。光于前,裕于后。

人遗子,金满嬴。我教子,惟一经。勤有功,戏无益。戒之哉,宜勉力。

 
2007年08月26日 星期日 上午 09:58

赠曾志
陶铸
重上战场我亦难,感君情厚逼云端。
无情白发催寒暑,蒙垢余生抑苦酸。
病马也知嘶枥晚,枯葵更觉怯霜残。
如烟往事俱忘却,心底无私天地宽。
************************************************************

注:曾志是陶铸的妻子。


陶铸,中共中央政治局常委、副总理。文革中曾任中央文革小组顾问。文革中由于江青拉他在一次中央会议上带头对邓小平同志发难被拒绝,以及为保一些干部,曾跟江青、陈伯达顶得历害,江青对陶铸几次发脾气。

在1967年1月4日,江青、康生、陈伯达突然在接见“武汉赴广州专揪王任重革命造反团”时宣布:陶铸是“刘、邓路线”的忠实执行者,“中国最大的保皇派”,要“发动群众”,“揪出来”。立即,“打倒陶铸!”的标语、传单布满全国。陶铸很快失去了人身自由,被单独幽禁于北京旁卐字廊住所。在1967年至1969年两年多的圈禁中,陶铸作为一名诗人,在磨难中留下了宝贵的诗篇。

在长达两年的关押中,陶铸不能见人,饮食有专人监视。除了被人带出去看大字报,平时不许出屋,只有在晚饭后可以在屋外廊下放放风。陶铸女儿陶斯亮在《一封终于发出的信》中回忆说,l967年8月一群彪形大汉闯入卐字廊,拉陶铸去批斗,陶铸和曾志夫妻二人站在台上,有人故意制造气氛,摄制电影,准备向全国放映。陶铸怒火郁积胸中,归来后在室内徘徊,象是一头笼中的猛兽。陶斯亮在回忆录中讲,她从此不爱走动物园,“因为每当我看到孩子们兴高彩烈地逗弄笼里的老虎时,我就立即想到您(陶铸)一种触动隐伤的痛苦,常常摧我泪下……”在幽禁中,陶铸向女儿陶斯亮讲历史上直节忠臣的故事,讲议朝范滂与擅权祸国的宦官阉党的斗争。陶铸愤激地说:“我就是因为不会给他们嗑头下跪才落得今天这个下场!以后,我还要凭着这点骨气活下去!”

1967年9月8日姚文元《评陶铸的两本书》在《人民日报》发表,陶铸在极端痛苦之中,在笔记中写道:“自杀,就是见不得人的事,不想把自己的问题弄清楚。当然也有这样可能,就是你去见了马克思,问题还是弄不清楚。那也不要紧,事实终归是事实,最后还是可以弄清楚,请相信四句话:

性质纵已定,还将心肝掏。
苌弘血化碧,哀痛总能消。

在1967年9月10日,姚文元文章发表后两天,陶斯亮被下令离京去东北白城子。1969年10月,林彪下达一号通令,陶铸押往合肥,被迫与曾志分离。43天后,陶铸在合肥死去。肥死去。陶铸在与曾志分手时,曾写有一首七律。

七律 赠曾志

重上战场我亦难,感君情厚逼云端。
无情白发催寒暑,蒙垢余生抑苦酸。
病马也知嘶枥晚,枯葵更觉怯霜寒。
如烟往事俱忘却,心底无私天自宽。

在卐字廊,陶铸还留下一首七律:

七律 1969

卐字廊前花木森,风送芬芳入杳冥。
静坐偶欣唯蝶舞,夜眠深苦长蚊鸣。
汉家狱辱周何怨,宋室廷刑岳慨承。
人世烦冤终不免,求仁奚用为身名。

1969年春天大手术后,陶铸力弱体衰,每日在室中读书练字,用毛笔将这首七律写在旧报纸上,这首诗夹杂在毛主席和鲁迅的诗词中间,加以行书难认,才得以保存。

诗中“周何怨”指汉名将周勃与其子周亚夫被谗入狱,周亚大冤死狱中一事。“岳慨承”指岳飞冤案。

 
2007年07月07日 星期六 下午 10:09

写给我的儿子

  你是在我们的期待中来到这个世界上的,结婚五年了,你才姗姗而来。
  在你出生之前,我和妻子说:“孩子是我们身上掉下来的肉,那么,我们一定会有一些感觉吧,要不象心电感应什么的来着,是不是?”妻子只是笑笑,她说:“会有的。”我努力努力的感受,一个月、二个月、三个月……十个月了,什么也没有,看来,我这种人是比较的迟钝的了,一直到你出世,还是什么感觉也没有。等你出世,感觉有了,但不是什么心电感应,而且感觉我们家多了一个小客人。为此,你妈妈的肚皮上还给开了个口子。你的妈妈似乎并不在乎,但我却不是很高兴,你怎么能这样呢?算了,我也不和你计较。
  记得你刚出来,眼睛都睁不开,整天除了吃就会睡,没事的时候,你哭都不愿意,除了拉了屎尿在身上。你整天面都臭臭的,不理人,眼睛也不随着人走,似乎整天都在想心事,你在想着什么呢?
  为了照顾好你这个小客人,你妈妈真的很累哦,几次,我和你妈妈说,让我来照看你几晚吧,不过,每次我总没把你照看好,因为你老爸总是睡得很死,你呢,也总是那么的不给你老爸面子,每回都给我闹出点花样,不是吐了奶、就是踢了被子感了冒。看来,只有你妈妈能对付得了你,唉,你可怜的妈妈。
  
  总算、你一岁半了,一年多,真不知怎么过来的。看着你一天天长大,会走路了,会依吖吖地含糊不清地说话了。我心里很开心,不过,内心里的感觉,你还是我的小客人。一个可爱的、不讲客气的、不懂事的小客人。
  我想说,你是一个很小心的家伙,唉,有点女孩子气呢,没碰过的东西你总是会很小心的试探,花园里的草地灯是我影象中你第一次试探的对象,看着美丽的草地灯,你很好奇,又有些害怕,看一眼,然后回头,紧紧地抱着妈妈,再看一眼再回头抱妈妈,最后试着伸出手去探,刚碰到立马缩回手,有时看得我都想笑,这时我才相信,愿来人的性格是天生的,可真没人教过你。
  你第一次摔跤的情况我记得很清楚,你不是一个容易摔跤的孩子,从你开始学走路,都是一步一步来,一点一点试,走不稳就会立马扶着身边的东西,不过,那一次你真的是高兴过头了,没看见地上的小木盒,结果给拌了一下,摔倒了,最不走运的是,你的头正好碰在门框的角上。当时你就痛得大哭起来,吓了我和你妈妈一跳。感觉那痛象是在我身上,在我心里,很深刻的那种,从那天开始,我知道了,心电感应是不会有了,但你的痛就是我的痛,你的快乐就是我的快乐。
  
  我会一直把你当成我家的客人的。我不会打你,当然,保不准会在生气的时候轻轻拍拍你的屁屁,不过,以你现在的性情,每次闯了祸,我还没来得及生气,你就先哭闹起来了,我哪有机会去想打你呢?哄你还来不及。
  我会把家里最好的食品给你,可是,让人愁的是,现在的孩子啊,什么都不喜欢吃,除了哪几瓶牛奶是你的最爱,有时我在想,是否瑶池上的琼也是奶制品呢?你真想修仙不成?我会买最好玩的玩具给你玩,不过,每回看见我的笔记本电脑,就要爬过来拍打,难道这世上最好玩的玩具竟是电脑不成?我亲爱的小客人,你还不到玩它的时候啊!这东西摔坏了我还真受不起,你老爸还没富到让你摔本本玩的程度。
  我会教你说话、教你算数、陪你学英语、物理……希望你学得不会像我一样太累,你可知道,那是我们每一个人必须的基本。我不希望你像很多人一样,连个电灯开关坏了也不会修,看不懂英文资料,玩不转电脑……你至少该像你老爸我一样,虽然什么都不精通,但至少什么都懂点。我要是没教会你,我会对不起把你送到我们家里的命运女神的,你说是吗?
  你不要担心,我也会陪着你一起去玩的,去山林、原野、海边。我会陪你去山花繁盛处看雨,陪你去波涛惊怒里放歌。
  如果你不想在我们的看护下,或独自、或结伴出游,我们当然会很担心的,你可一定得平安回家。我们希望你一生平安,我们希望你没有一丝一毫的伤痛,最好,连蚊子也不会给咬上一口。
  
  十多年后,你会懂事的,你会长大,那时的你会是什么样的呢?会听我们的话吗?会很聪明吗?会让大人们喜欢吗?
  首先我希望你是一个健康的孩子。我还希望你是个聪明的孩子,这样,你就不会在这竞争激烈的社会中活得太累。然后呢,我们希望你是一个真诚的孩子,也许,真诚会让你失去一些得到小便宜的机会,会让你吃一些小亏,但至少不会让你上大当的。最后,我希望你是一个帅气的孩子,不为别的,至少对得起你妈妈的美丽。
  那时我们会老的,人生的道路已经定格,你老爸和老妈也就这么点儿出息了,你呢?是如你老爸一样在内心里潇洒不羁呢,还是象你妈妈一样好强自尊而敏感?但无论如何,我希望你是聪明而勤奋的,因为无论你是想潇脱还是想争强,那都是需要内在的实力为基础的,失去内在的能力的潇洒只能称为放浪,争强只能称为妒嫉。
  
  儿子,你是我们的客人,命运女神送来的贵客。我希望你能在我们这个家开开心心的生活,希望你总是有着幸福的笑容。我们不能给你奢靡的生活,却能给你我们最真诚的爱。有一天我们会老,会死的。而你呢,终将作为我们生的延继,带着我们给你带去的爱、自信、知识去创造一个新家,一个新的温暖的小港,并将我们这份受无限的延继。我亲爱的儿子,会开心吗?你会愿意吗?


  ——你的老爸 述于二〇〇七年七月十二日

 
2007年05月24日 星期四 下午 01:50

戴望舒

撑着油纸伞,独自
彷徨在悠长、悠长
又寂寥的雨巷,
我希望逢着
一个丁香一样地
结着愁怨的姑娘。

她是有
丁香一样的颜色,
丁香一样的芬芳,
丁香一样的忧愁,
在雨中哀怨,
哀怨又彷徨;

她彷徨在这寂寥的雨巷,
撑着油纸伞
像我一样,
像我一样地
默默彳亍着
冷漠、凄清,又惆怅。

她默默地走近,
走近,又投出
太息一般的眼光
她飘过
像梦一般地,
像梦一般地凄婉迷茫。

像梦中飘过
一枝丁香地,
我身旁飘过这个女郎;
她默默地远了,远了,
到了颓圮的篱墙,
走尽这雨巷。

在雨的哀曲里,
消了她的颜色,
散了她的芬芳,
消散了,甚至她的
太息般的眼光
丁香般的惆怅。

撑着油纸伞,独自
彷徨在悠长、悠长
又寂寥的雨巷,
我希望飘过
一个丁香一样地
结着愁怨的姑娘。

 
2006年09月28日 星期四 下午 07:49
桌上的烟慢慢的燃着,我的时间也在慢慢的延续着。
这样静静守望的日子很快就要结束了,我不能决定我的去留,
也不能改变别人的意愿,在我的世界里更多的是顺从。
这个美好的夏天似乎什么也不想给我留下,

只有这静静的黑夜和那盒香烟陪伴着我。
忘了时间,忘了人会改变,甚至忘记了昨天的亏欠,
有些事情真的不会明白,
不想在为别人改变。
 
     
 
 
背景音乐
 
 
个人档案
 
 哎呀……
男, 25岁
江西 吉安 
加为好友
 
   
 
最新照片
 
   
 
日历
 
     
 
留言板
 

很幸福的一家.
 

端午节快乐....多多吃粽子哟...