甜咖啡

          我的IT空間

          一、卸載jdk1.4

          由于Redhat Enterprise Linux 5.6 中自帶安裝了jdk1.4.2的,所以在安裝jdk1.6前我把jdk1.4.2的卸了,步驟如下:

          1、打開終端輸入 yum remove java
          終端顯示 Is this ok [y/N]:
          輸入y ,按回車。
          終端顯示 Complete! 此時jdk1.4已被卸了。
          二、安裝jdk1.6

          1.下載:jdk-1_5_0_06-linux-i586-rpm.bin
             地址:http://java.sun.com/j2se/1.5.0/download.jsp
          2.給文件加上可執(zhí)行權(quán)限
             [root@esprit java]# chmod +x jdk-1_5_0_06-linux-i586-rpm.bin
          chmod +x jdk-6u31-linux-i586-rpm.bin
          3.執(zhí)行jdk-1_5_0_06-linux-i586-rpm.bin
             [root@esprit java]# ./jdk-1_5_0_06-linux-i586-rpm.bin
          ./jdk-6u31-linux-i586-rpm.bin
             執(zhí)行后生成jdk-6u31-linux-i586.rpm
          4.安裝jdk-6u31-linux-i586.rpm
          rpm -ivh jdk-6u31-linux-i586.rpm
          ########################################### [100%]
          package jdk-1.6.0_31-fcs is already installed
          這里我jdk安裝在/usr/java目錄下

          三、配置java環(huán)境變量

           環(huán)境變量配置有三種方法(分別是:修改/etc/profile文件,修改用戶目錄下的.bashrc文件,直接在shell下修改)
          這里我只講我用到的修改/etc/profile文件
             [root@esprit java]# vi /etc/profile
             打開文件后,按 I 鍵,在文件后添加:
           JAVA_HOME =/ usr / java / jdk1.6.0_31
           PATH = $JAVA_HOME / bin:$PATH
           CLASSPATH = .:$JAVA_HOME / lib / tools.jar:$JAVA_HOME / lib / dt.jar:$JAVA_HOME/lib
           export JAVA_HOME PATH CLASSPATH
           
             按esc 鍵
             輸入:wq 保存退出。
             重新登入

          四、檢查jdk是否裝好

          在命令行輸入: java -version

          如果顯示版本信息,表示已經(jīng)安裝配置成功

          五、卸載jdk1.6

          輸入 rpm -qa|grep jdk
          顯示 jdk-1.6.0_24-fcs
          卸載 rpm -e –nodeps jdk-1.6.0_24-fcs

          posted @ 2012-09-19 14:19 甜咖啡 閱讀(7109) | 評論 (1)編輯 收藏

          package com.ky.ui.util;

          import java.awt.Color;
          import java.awt.Font;
          import java.awt.Graphics;
          import java.awt.Image;
          import java.awt.image.BufferedImage;
          import java.io.File;
          import java.io.FileOutputStream;

          import javax.imageio.ImageIO;

          import com.sun.image.codec.jpeg.JPEGCodec;
          import com.sun.image.codec.jpeg.JPEGImageEncoder;

           

          /**
          Email:

          上午11:18:19
          */
          public final class ImgRead{

          // public final static String getPressImgPath(){
          // return ApplicationContext.getRealPath("/template/data/util/shuiyin.gif");
          // }

          /** *//**
          * 把圖片印刷到圖片上
          * @param pressImg -- 水印文件
          * @param targetImg -- 目標(biāo)文件
          * @param x
          * @param y
          */
          public final static void pressImage(String pressImg, String targetImg, int x, int y){
          try {
          File _file = new File(targetImg);
          Image src = ImageIO.read(_file);
          int wideth = src.getWidth(null);
          int height = src.getHeight(null);
          BufferedImage image = new BufferedImage(wideth, height,
          BufferedImage.TYPE_INT_RGB);
          Graphics g = image.createGraphics();
          g.drawImage(src, 0, 0, wideth, height, null);

          // 水印文件
          File _filebiao = new File(pressImg);
          Image src_biao = ImageIO.read(_filebiao);
          int wideth_biao = src_biao.getWidth(null);
          int height_biao = src_biao.getHeight(null);
          g.drawImage(src_biao, wideth - wideth_biao - x, height - height_biao -y, wideth_biao,
          height_biao, null);
          // /
          g.dispose();
          FileOutputStream out = new FileOutputStream(targetImg);
          JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
          encoder.encode(image);
          out.close();
          } catch (Exception e){
          e.printStackTrace();
          }
          }

          /** *//**
          * 打印文字水印圖片
          * @param pressText --文字
          * @param targetImg -- 目標(biāo)圖片
          * @param fontName -- 字體名
          * @param fontStyle -- 字體樣式
          * @param color -- 字體顏色
          * @param fontSize -- 字體大小
          * @param x -- 偏移量
          * @param y
          */

          public static void pressText(String pressText, String targetImg, String fontName,int fontStyle, int color, int fontSize, int x, int y){
          try{
          File _file = new File(targetImg);
          Image src = ImageIO.read(_file);
          int wideth = src.getWidth(null);
          int height = src.getHeight(null);
          BufferedImage image = new BufferedImage(wideth, height,
          BufferedImage.TYPE_INT_RGB);
          Graphics g = image.createGraphics();
          g.drawImage(src, 0, 0, wideth, height, null);
          // String s=" g.setColor(Color.RED);
          g.setFont(new Font(fontName, fontStyle, fontSize));

          g.drawString(pressText, wideth - fontSize - x, height - fontSize/2 - y);
          g.dispose();
          FileOutputStream out = new FileOutputStream(targetImg);
          JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
          encoder.encode(image);
          out.close();
          } catch (Exception e){
          System.out.println(e);
          }
          }

          public static void main(String[] args){
          pressImage("C:/foot_05.gif", "c:/Chart.jpg", 20 ,20);
          }
          }

          posted @ 2012-09-08 19:51 甜咖啡 閱讀(304) | 評論 (0)編輯 收藏

          //  獲取屏幕的邊界
            Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(frame.getGraphicsConfiguration());
          //  獲取底部任務(wù)欄高度
            int taskBarHeight = screenInsets.bottom; 

          posted @ 2012-09-08 19:46 甜咖啡 閱讀(1611) | 評論 (0)編輯 收藏

          1、  下載vsftpd

          # wget ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.3.2.tar.gz

          2、  解壓、安裝vsftpd

          # tar xvfz vsftpd-2.3.2.tar.gz

          # cd vsftpd-2.3.2

          # make

          make命令成功執(zhí)行后,您將看到vsftpd文件獲得當(dāng)前目錄中創(chuàng)建。

          # ls -l vsftpd

          3、  安裝 vsftpd d Linux

          # make install

          make install,確保vsftpd文件復(fù)制到/ usr / local / sbin目錄。

          # ls -l /usr/local/sbin/vsftpd

          4、  復(fù)制vsftpd手冊頁到/usr/share/man/man8,man5

          # cp vsftpd.8 /usr/share/man/man8/

          # cp vsftpd.conf.5 /usr/share/man/man5/

          5、  拷貝vsftpd.cond配置文件

          # cp vsftpd.conf /etc

          6、   設(shè)置Anonymouse FTP訪問vsftpd

          # mkdir /var/ftp/

          # chown root.root /var/ftp

          # chmod og-w /var/ftp

           

          ftp localhost

          Connected to dotcom.

          220 (vsFTPd 2.3.2)

          530 Please login with USER and PASS.

          KERBEROS_V4 rejected as an authentication type

          Name (localhost:root): anonymous

          331 Please specify the password.

          Password:

          230 Login successful.

          Remote system type is UNIX.

          Using binary mode to transfer files.

          ftp>

          在這個階段,如果你試圖登錄與任何其他賬戶(除了匿名,和ftp),它就會失敗,如下所示

          # ftp localhost

          Connected to dotcom.

          220 (vsFTPd 2.3.2)

          530 Please login with USER and PASS.

          KERBEROS_V4 rejected as an authentication type

          Name (localhost:root): ramesh

          530 This FTP server is anonymous only.

          Login failed.

          ftp>

          7、   允許LINIX登錄使用vsftp

          # cp RedHat/vsftpd.pam /etc/pam.d/ftp

          #local_enable=YES

          # ftp localhost

          Connected to dotcom.

          220 (vsFTPd 2.3.2)

          530 Please login with USER and PASS.

          KERBEROS_V4 rejected as an authentication type

          Name (localhost:root): ramesh

          Password:

          230 Login successful.

          Remote system type is UNIX.

          Using binary mode to transfer files.

          ftp>

          切記再每次修改完vsftpd.conf文件之后要重啟一下vsftpd

          # ps -ef | grep vsftpd

          # kill -9 {vsftpd-pid}

          # /usr/local/sbin/vsftpd &

           

           

          如果還不能登錄成功,那么要關(guān)閉系統(tǒng)其他的ftp服務(wù)和防火墻

          Service xinetd stop

          Service iptables stop

          posted @ 2012-08-22 16:15 甜咖啡 閱讀(262) | 評論 (0)編輯 收藏
          posted @ 2012-05-17 17:56 甜咖啡 閱讀(182) | 評論 (0)編輯 收藏
               摘要: 各種排序算法:冒擇路(入)兮(稀)快歸堆,桶式排序,基數(shù)排序 冒泡排序,選擇排序,插入排序,稀爾排序,快速排序,歸并排序,堆排序,桶式排序,基數(shù)排序 一、冒泡排序(BubbleSort) 1. 基本思想:   兩兩比較待排序數(shù)據(jù)元素的大小,發(fā)現(xiàn)兩個數(shù)據(jù)元素的次序相反時即進(jìn)行交換,直到?jīng)]有反序的數(shù)據(jù)元素為止。 2. 排序過程:   設(shè)想被排序的數(shù)組R[1..N]垂直豎立,將每個數(shù)據(jù)元素看作有重量的氣...  閱讀全文
          posted @ 2012-05-17 17:52 甜咖啡 閱讀(838) | 評論 (0)編輯 收藏
               摘要: Java反射機(jī)制是Java語言被視為準(zhǔn)動態(tài)語言的關(guān)鍵性質(zhì)。Java反射機(jī)制的核心就是允許在運(yùn)行時通過Java Reflection APIs來取得已知名字的class類的相關(guān)信息,動態(tài)地生成此類,并調(diào)用其方法或修改其域(甚至是本身聲明為private的域或方法)。 也許你使用Java已經(jīng)很長時間了,可是幾乎不會用到Java反射機(jī)制。你會嗤之以鼻地告訴我,Java反射機(jī)制沒啥用...  閱讀全文
          posted @ 2012-05-17 17:07 甜咖啡 閱讀(282) | 評論 (0)編輯 收藏
          1.使用mysqladmin修改mysql密碼
          C:\>mysqladmin -udbuser -p password newpass
          Enter password: oldpass
          當(dāng)然用此命令的前提是你把mysql加入了環(huán)境變量,如果沒有加入環(huán)境變量的話那只能在命令行下cd到mysqladmin所在的目錄下與此那個次命令了!
          -----------------------------------------
          2.重置root密碼
          方法一:
          在my.ini的[mysqld]字段加入:
          skip-grant-tables
          重啟mysql服務(wù),這時的mysql不需要密碼即可登錄數(shù)據(jù)庫
          然后進(jìn)入mysql
          mysql>use mysql;
          mysql>update user set password=password('新密碼') WHERE User='root';
          mysql>flush privileges;
          運(yùn)行之后最后去掉my.ini中的skip-grant-tables,重啟mysqld即可。
          修改mysql密碼方法二:
          不使用修改my.ini重啟服務(wù)的方法,通過非服務(wù)方式加skip-grant-tables運(yùn)行mysql來修改mysql密碼
          停止mysql服務(wù)
          打開命令行窗口,在bin目錄下使用mysqld-nt.exe啟動,即在命令行窗口執(zhí)行: mysqld-nt --skip-grant-tables
          然后另外打開一個命令行窗口,登錄mysql,此時無需輸入mysql密碼即可進(jìn)入。
          按以上方法修改好密碼后,關(guān)閉命令行運(yùn)行mysql的那個窗口,此時即關(guān)閉了mysql,如果發(fā)現(xiàn)mysql仍在運(yùn)行的話可以結(jié)束掉對應(yīng)進(jìn)程來關(guān)閉。
          啟動mysql服務(wù)

          -----------------------------------------

          記住此方法,走遍天下無mysql密碼

          posted @ 2012-05-16 18:38 甜咖啡 閱讀(204) | 評論 (0)編輯 收藏

          先假設(shè)一個ftp地址 用戶名 密碼

                FTP Server: home4u.at.china.com

            User: yepanghuang

            Password: abc123

          打開windows的開始菜單,執(zhí)行“運(yùn)行”命令,在對話框中輸入ftp,按下“確定”按鈕將會切換至DOS窗口,出現(xiàn)命令提示符

                ftp>鍵入命令連接FTP服務(wù)器

            ftp> open home4u.at.china.com (回車)

            稍等片刻,屏幕提示連接成功:

            ftp> connected to home4u.china.com

            接下來服務(wù)器詢問用戶名和口令,分別輸入yepanghuang和abc123,待認(rèn)證通過即可。

          windows下ftp上傳文件:

                比如要把 D:\index.html上傳至服務(wù)器的根目錄中,可以鍵入:

            ftp> put D:\index.html (回車)

            當(dāng)屏幕提示你已經(jīng)傳輸完畢,可以鍵入相關(guān)命令查看:

            ftp> dir (回車)

          windows下ftp上傳下載:

                假設(shè)要把服務(wù)器\images目錄中的所有.jpg文件下載至本機(jī)中,可以輸入指令:

            ftp> cd images(回車) [注:進(jìn)入\images目錄]

            ftp> mget *.jpg

            windows下ftp上傳與下載工作完畢,鍵入bye中斷連接。

            ftp> bye(回車)

          下面是一些常用的FTP命令:

            1. open:與服務(wù)器相連接;

            2. send(put):上傳文件;

            3. get:下載文件;

            4. mget:下載多個文件;

            5. cd:切換目錄;

            6. dir:查看當(dāng)前目錄下的文件;

            7. del:刪除文件;

            8. bye:中斷與服務(wù)器的連接。

            如果想了解更多,可以鍵入

            ftp> help (回車)

          查看命令集

            ascii: 設(shè)定以ASCII方式傳送文件(缺省值)

            bell: 每完成一次文件傳送,報警提示

            binary: 設(shè)定以二進(jìn)制方式傳送文件

            bye: 終止主機(jī)FTP進(jìn)程,并退出FTP管理方式

            case: 當(dāng)為ON時,用MGET命令拷貝的文件名到本地機(jī)器中,全部轉(zhuǎn)換為小寫字母

            cd: 同UNIX的CD命令

            cdup: 返回上一級目錄

            chmod: 改變遠(yuǎn)端主機(jī)的文件權(quán)限

            close: 終止遠(yuǎn)端的FTP進(jìn)程,返回到FTP命令狀態(tài),所有的宏定義都被刪除

            delete: 刪除遠(yuǎn)端主機(jī)中的文件

            dir [remote-directory] [local-file]: 列出當(dāng)前遠(yuǎn)端主機(jī)目錄中的文件.如果有本地文件,就將結(jié)果寫至本地文件

            get [remote-file] [local-file]: 從遠(yuǎn)端主機(jī)中傳送至本地主機(jī)中

            help [command]: 輸出命令的解釋

            lcd: 改變當(dāng)前本地主機(jī)的工作目錄,如果缺省,就轉(zhuǎn)到當(dāng)前用戶的HOME目錄

            ls [remote-directory] [local-file]: 同DIR

          posted @ 2012-05-16 18:35 甜咖啡 閱讀(9146) | 評論 (0)編輯 收藏

          其實在網(wǎng)上也看到過一些文章,介紹如何讓java程序以window服務(wù)的方式啟動。

          今天有空,就想用c寫一個window服務(wù),在服務(wù)啟動時來啟動一個java程序。

          因為在c方面,我十足菜鳥,先到網(wǎng)上搜索了一下關(guān)于如何用c寫出windows服務(wù),找到一篇介紹的相當(dāng)詳細(xì),參照介紹寫了一個window服務(wù)。

          測試的過程中遇到一個問題,由于我的java程序啟動時會在系統(tǒng)托盤顯示一個小圖標(biāo),但通過c寫的window服務(wù)啟運(yùn)這個java程序后,系統(tǒng)托盤里沒有顯示小圖標(biāo)。

          再搜索,原來:

          windows服務(wù)程序默認(rèn)是工作于WinLogon桌面的,服務(wù)啟動時不會顯示GUI界面.可以打開控制面板->服務(wù),查看服務(wù)的屬性->[登錄]-[允許服務(wù)與桌面交互],打上鉤后,系統(tǒng)托盤就能顯示在任務(wù)欄。

           

           

          用C寫一個windows服務(wù)

          來源:http://www.vckbase.com/document/viewdoc/?id=1474

          摘要

            Windows 服務(wù)被設(shè)計用于需要在后臺運(yùn)行的應(yīng)用程序以及實現(xiàn)沒有用戶交互的任務(wù)。為了學(xué)習(xí)這種控制臺應(yīng)用程序的基礎(chǔ)知識,C(不是C++)是最佳選擇。本文將建立并實現(xiàn)一個簡單的服務(wù)程序,其功能是查詢系統(tǒng)中可用物理內(nèi)存數(shù)量,然后將結(jié)果寫入一個文本文件。最后,你可以用所學(xué)知識編寫自己的 Windows 服務(wù)。
            當(dāng)初我寫第一個 NT 服務(wù)時,我到 MSDN 上找例子。在那里我找到了一篇 Nigel Thompson 寫的文章:“Creating a Simple Win32 Service in C++”,這篇文章附帶一個 C++ 例子。雖然這篇文章很好地解釋了服務(wù)的開發(fā)過程,但是,我仍然感覺缺少我需要的重要信息。我想理解通過什么框架,調(diào)用什么函數(shù),以及何時調(diào)用,但 C++ 在這方面沒有讓我輕松多少。面向?qū)ο蟮姆椒ü倘环奖悖捎谟妙悓Φ讓?Win32 函數(shù)調(diào)用進(jìn)行了封裝,它不利于學(xué)習(xí)服務(wù)程序的基本知識。這就是為什么我覺得 C 更加適合于編寫初級服務(wù)程序或者實現(xiàn)簡單后臺任務(wù)的服務(wù)。在你對服務(wù)程序有了充分透徹的理解之后,用 C++ 編寫才能游刃有余。當(dāng)我離開原來的工作崗位,不得不向另一個人轉(zhuǎn)移我的知識的時候,利用我用 C 所寫的例子就非常容易解釋 NT 服務(wù)之所以然。
            服務(wù)是一個運(yùn)行在后臺并實現(xiàn)勿需用戶交互的任務(wù)的控制臺程序。Windows NT/2000/XP 操作系統(tǒng)提供為服務(wù)程序提供專門的支持。人們可以用服務(wù)控制面板來配置安裝好的服務(wù)程序,也就是 Windows 2000/XP 控制面板|管理工具中的“服務(wù)”(或在“開始”|“運(yùn)行”對話框中輸入 services.msc /s——譯者注)。可以將服務(wù)配置成操作系統(tǒng)啟動時自動啟動,這樣你就不必每次再重啟系統(tǒng)后還要手動啟動服務(wù)。
            本文將首先解釋如何創(chuàng)建一個定期查詢可用物理內(nèi)存并將結(jié)果寫入某個文本文件的服務(wù)。然后指導(dǎo)你完成生成,安裝和實現(xiàn)服務(wù)的整個過程。


          第一步:主函數(shù)和全局定義

          首先,包含所需的頭文件。例子要調(diào)用 Win32 函數(shù)(windows.h)和磁盤文件寫入(stdio.h):

          #include <windows.h>
          #include <stdio.h>

          接著,定義兩個常量:

          #define SLEEP_TIME 5000
          #define LOGFILE "C:\\MyServices\\memstatus.txt"

          SLEEP_TIME 指定兩次連續(xù)查詢可用內(nèi)存之間的毫秒間隔。在第二步中編寫服務(wù)工作循環(huán)的時候要使用該常量。
          LOGFILE 定義日志文件的路徑,你將會用 WriteToLog 函數(shù)將內(nèi)存查詢的結(jié)果輸出到該文件,WriteToLog 函數(shù)定義如下:

          int WriteToLog(char* str)
          {
              FILE* log;
              log = fopen(LOGFILE, "a+");
              if (log == NULL)
              return -1;
              fprintf(log, "%s\n", str);
              fclose(log);
              return 0;
          }

          聲明幾個全局變量,以便在程序的多個函數(shù)之間共享它們值。此外,做一個函數(shù)的前向定義:

          SERVICE_STATUS ServiceStatus; 
          SERVICE_STATUS_HANDLE hStatus; 
          
          void ServiceMain(int argc, char** argv); 
          void ControlHandler(DWORD request); 
          int InitService();

            現(xiàn)在,準(zhǔn)備工作已經(jīng)就緒,你可以開始編碼了。服務(wù)程序控制臺程序的一個子集。因此,開始你可以定義一個 main 函數(shù),它是程序的入口點。對于服務(wù)程序來說,main 的代碼令人驚訝地簡短,因為它只創(chuàng)建分派表并啟動控制分派機(jī)。

          void main() 
          { 
              SERVICE_TABLE_ENTRY ServiceTable[2];
              ServiceTable[0].lpServiceName = "MemoryStatus";
              ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
              
              ServiceTable[1].lpServiceName = NULL;
              ServiceTable[1].lpServiceProc = NULL;
          
              // 啟動服務(wù)的控制分派機(jī)線程
              StartServiceCtrlDispatcher(ServiceTable); 
          }

            一個程序可能包含若干個服務(wù)。每一個服務(wù)都必須列于專門的分派表中(為此該程序定義了一個 ServiceTable 結(jié)構(gòu)數(shù)組)。這個表中的每一項都要在 SERVICE_TABLE_ENTRY 結(jié)構(gòu)之中。它有兩個域:

          • lpServiceName: 指向表示服務(wù)名稱字符串的指針;當(dāng)定義了多個服務(wù)時,那么這個域必須指定;
          • lpServiceProc: 指向服務(wù)主函數(shù)的指針(服務(wù)入口點);

            分派表的最后一項必須是服務(wù)名和服務(wù)主函數(shù)域的 NULL 指針,文本例子程序中只宿主一個服務(wù),所以服務(wù)名的定義是可選的。
            服務(wù)控制管理器(SCM:Services Control Manager)是一個管理系統(tǒng)所有服務(wù)的進(jìn)程。當(dāng) SCM 啟動某個服務(wù)時,它等待某個進(jìn)程的主線程來調(diào)用 StartServiceCtrlDispatcher 函數(shù)。將分派表傳遞給 StartServiceCtrlDispatcher。這將把調(diào)用進(jìn)程的主線程轉(zhuǎn)換為控制分派器。該分派器啟動一個新線程,該線程運(yùn)行分派表中每個服務(wù)的 ServiceMain 函數(shù)(本文例子中只有一個服務(wù))分派器還監(jiān)視程序中所有服務(wù)的執(zhí)行情況。然后分派器將控制請求從 SCM 傳給服務(wù)。

          注意:如果 StartServiceCtrlDispatcher 函數(shù)30秒沒有被調(diào)用,便會報錯,為了避免這種情況,我們必須在 ServiceMain 函數(shù)中(參見本文例子)或在非主函數(shù)的單獨線程中初始化服務(wù)分派表。本文所描述的服務(wù)不需要防范這樣的情況。

            分派表中所有的服務(wù)執(zhí)行完之后(例如,用戶通過“服務(wù)”控制面板程序停止它們),或者發(fā)生錯誤時。StartServiceCtrlDispatcher 調(diào)用返回。然后主進(jìn)程終止。


          第二步:ServiceMain 函數(shù)

            Listing 1 展示了 ServiceMain 的代碼。該函數(shù)是服務(wù)的入口點。它運(yùn)行在一個單獨的線程當(dāng)中,這個線程是由控制分派器創(chuàng)建的。ServiceMain 應(yīng)該盡可能早早為服務(wù)注冊控制處理器。這要通過調(diào)用 RegisterServiceCtrlHadler 函數(shù)來實現(xiàn)。你要將兩個參數(shù)傳遞給此函數(shù):服務(wù)名和指向 ControlHandlerfunction 的指針。
            它指示控制分派器調(diào)用 ControlHandler 函數(shù)處理 SCM 控制請求。注冊完控制處理器之后,獲得狀態(tài)句柄(hStatus)。通過調(diào)用 SetServiceStatus 函數(shù),用 hStatus 向 SCM 報告服務(wù)的狀態(tài)。
          Listing 1 展示了如何指定服務(wù)特征和其當(dāng)前狀態(tài)來初始化 ServiceStatus 結(jié)構(gòu),ServiceStatus 結(jié)構(gòu)的每個域都有其用途:

          • dwServiceType:指示服務(wù)類型,創(chuàng)建 Win32 服務(wù)。賦值 SERVICE_WIN32;
          • dwCurrentState:指定服務(wù)的當(dāng)前狀態(tài)。因為服務(wù)的初始化在這里沒有完成,所以這里的狀態(tài)為 SERVICE_START_PENDING;
          • dwControlsAccepted:這個域通知 SCM 服務(wù)接受哪個域。本文例子是允許 STOP 和 SHUTDOWN 請求。處理控制請求將在第三步討論;
          • dwWin32ExitCode 和 dwServiceSpecificExitCode:這兩個域在你終止服務(wù)并報告退出細(xì)節(jié)時很有用。初始化服務(wù)時并不退出,因此,它們的值為 0;
          • dwCheckPoint 和 dwWaitHint:這兩個域表示初始化某個服務(wù)進(jìn)程時要30秒以上。本文例子服務(wù)的初始化過程很短,所以這兩個域的值都為 0。

            調(diào)用 SetServiceStatus 函數(shù)向 SCM 報告服務(wù)的狀態(tài)時。要提供 hStatus 句柄和 ServiceStatus 結(jié)構(gòu)。注意 ServiceStatus 一個全局變量,所以你可以跨多個函數(shù)使用它。ServiceMain 函數(shù)中,你給結(jié)構(gòu)的幾個域賦值,它們在服務(wù)運(yùn)行的整個過程中都保持不變,比如:dwServiceType。
            在報告了服務(wù)狀態(tài)之后,你可以調(diào)用 InitService 函數(shù)來完成初始化。這個函數(shù)只是添加一個說明性字符串到日志文件。如下面代碼所示:

          // 服務(wù)初始化
          int InitService() 
          { 
              int result;
              result = WriteToLog("Monitoring started.");
              return(result); 
          }

            在 ServiceMain 中,檢查 InitService 函數(shù)的返回值。如果初始化有錯(因為有可能寫日志文件失敗),則將服務(wù)狀態(tài)置為終止并退出 ServiceMain:

          error = InitService(); 
          if (error) 
          {
              // 初始化失敗,終止服務(wù)
              ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
              ServiceStatus.dwWin32ExitCode = -1; 
              SetServiceStatus(hStatus, &ServiceStatus); 
              // 退出 ServiceMain
              return; 
          }

          如果初始化成功,則向 SCM 報告狀態(tài):

          // 向 SCM 報告運(yùn)行狀態(tài) 
          ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
          SetServiceStatus (hStatus, &ServiceStatus);

          接著,啟動工作循環(huán)。每五秒鐘查詢一個可用物理內(nèi)存并將結(jié)果寫入日志文件。

          如 Listing 1 所示,循環(huán)一直到服務(wù)的狀態(tài)為 SERVICE_RUNNING 或日志文件寫入出錯為止。狀態(tài)可能在 ControlHandler 函數(shù)響應(yīng) SCM 控制請求時修改。
           

          第三步:處理控制請求

            在第二步中,你用 ServiceMain 函數(shù)注冊了控制處理器函數(shù)。控制處理器與處理各種 Windows 消息的窗口回調(diào)函數(shù)非常類似。它檢查 SCM 發(fā)送了什么請求并采取相應(yīng)行動。
            每次你調(diào)用 SetServiceStatus 函數(shù)的時候,必須指定服務(wù)接收 STOP 和 SHUTDOWN 請求。Listing 2 示范了如何在 ControlHandler 函數(shù)中處理它們。
            STOP 請求是 SCM 終止服務(wù)的時候發(fā)送的。例如,如果用戶在“服務(wù)”控制面板中手動終止服務(wù)。SHUTDOWN 請求是關(guān)閉機(jī)器時,由 SCM 發(fā)送給所有運(yùn)行中服務(wù)的請求。兩種情況的處理方式相同:

          • 寫日志文件,監(jiān)視停止;
          • 向 SCM 報告 SERVICE_STOPPED 狀態(tài);

            由于 ServiceStatus 結(jié)構(gòu)對于整個程序而言為全局量,ServiceStatus 中的工作循環(huán)在當(dāng)前狀態(tài)改變或服務(wù)終止后停止。其它的控制請求如:PAUSE 和 CONTINUE 在本文的例子沒有處理。
            控制處理器函數(shù)必須報告服務(wù)狀態(tài),即便 SCM 每次發(fā)送控制請求的時候狀態(tài)保持相同。因此,不管響應(yīng)什么請求,都要調(diào)用 SetServiceStatus。


          圖一 顯示 MemoryStatus 服務(wù)的服務(wù)控制面板


          第四步:安裝和配置服務(wù)

            程序編好了,將之編譯成 exe 文件。本文例子創(chuàng)建的文件叫 MemoryStatus.exe,將它拷貝到 C:\MyServices 文件夾。為了在機(jī)器上安裝這個服務(wù),需要用 SC.EXE 可執(zhí)行文件,它是 Win32 Platform SDK 中附帶的一個工具。(譯者注:Visaul Studio .NET 2003 IDE 環(huán)境中也有這個工具,具體存放位置在:C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin\winnt)。使用這個實用工具可以安裝和移除服務(wù)。其它控制操作將通過服務(wù)控制面板來完成。以下是用命令行安裝 MemoryStatus 服務(wù)的方法:

          sc create MemoryStatus binpath= c:\MyServices\MemoryStatus.exe

            發(fā)出此創(chuàng)建命令。指定服務(wù)名和二進(jìn)制文件的路徑(注意 binpath= 和路徑之間的那個空格)。安裝成功后,便可以用服務(wù)控制面板來控制這個服務(wù)(參見圖一)。用控制面板的工具欄啟動和終止這個服務(wù)。


          圖二 MemoryStatus 服務(wù)的屬性窗口

            MemoryStatus 的啟動類型是手動,也就是說根據(jù)需要來啟動這個服務(wù)。右鍵單擊該服務(wù),然后選擇上下文菜單中的“屬性”菜單項,此時顯示該服務(wù)的屬性窗口。在這里可以修改啟動類型以及其它設(shè)置。你還可以從“常規(guī)”標(biāo)簽中啟動/停止服務(wù)。以下是從系統(tǒng)中移除服務(wù)的方法:

          sc delete MemoryStatus

          指定 “delete” 選項和服務(wù)名。此服務(wù)將被標(biāo)記為刪除,下次西通重啟后,該服務(wù)將被完全移除。


          第五步:測試服務(wù)

            從服務(wù)控制面板啟動 MemoryStatus 服務(wù)。如果初始化不出錯,表示啟動成功。過一會兒將服務(wù)停止。檢查一下 C:\MyServices 文件夾中 memstatus.txt 文件的服務(wù)輸出。在我的機(jī)器上輸出是這樣的:

          Monitoring started.
          273469440
          273379328
          273133568
          273084416
          Monitoring stopped.

            為了測試 MemoryStatus 服務(wù)在出錯情況下的行為,可以將 memstatus.txt 文件設(shè)置成只讀。這樣一來,服務(wù)應(yīng)該無法啟動。
            去掉只讀屬性,啟動服務(wù),在將文件設(shè)成只讀。服務(wù)將停止執(zhí)行,因為此時日志文件寫入失敗。如果你更新服務(wù)控制面板的內(nèi)容,會發(fā)現(xiàn)服務(wù)狀態(tài)是已經(jīng)停止。
           

          開發(fā)更大更好的服務(wù)程序

            理解 Win32 服務(wù)的基本概念,使你能更好地用 C++ 來設(shè)計包裝類。包裝類隱藏了對底層 Win32 函數(shù)的調(diào)用并提供了一種舒適的通用接口。修改 MemoryStatus 程序代碼,創(chuàng)建滿足自己需要的服務(wù)!為了實現(xiàn)比本文例子所示范的更復(fù)雜的任務(wù),你可以創(chuàng)建多線程的服務(wù),將作業(yè)劃分成幾個工作者線程并從 ServiceMain 函數(shù)中監(jiān)視它們的執(zhí)行。


          posted @ 2012-04-24 11:58 甜咖啡 閱讀(1770) | 評論 (0)編輯 收藏

          最近的機(jī)器內(nèi)存又爆滿了,除了新增機(jī)器內(nèi)存外,還應(yīng)該好好review一下我們的代碼,有很多代碼編寫過于隨意化,這些不好的習(xí)慣或?qū)Τ绦蛘Z言的不了解是應(yīng)該好好打壓打壓了。

           

          下面是參考網(wǎng)絡(luò)資源總結(jié)的一些在Java編程中盡可能要做到的一些地方。
          1. 盡量在合適的場合使用單例
          使用單例可以減輕加載的負(fù)擔(dān),縮短加載的時間,提高加載的效率,但并不是所有地方都適用于單例,簡單來說,單例主要適用于以下三個方面:
          第一,控制資源的使用,通過線程同步來控制資源的并發(fā)訪問;
          第二,控制實例的產(chǎn)生,以達(dá)到節(jié)約資源的目的;
          第三,控制數(shù)據(jù)共享,在不建立直接關(guān)聯(lián)的條件下,讓多個不相關(guān)的進(jìn)程或線程之間實現(xiàn)通信。

          2. 盡量避免隨意使用靜態(tài)變量
          要知道,當(dāng)某個對象被定義為stataic變量所引用,那么gc通常是不會回收這個對象所占有的內(nèi)存,如
          Java代碼
          1. public class A{   
          2. static B b = new B();   
          3. }  
          public class A{ static B b = new B(); }
           
          此時靜態(tài)變量b的生命周期與A類同步,如果A類不會卸載,那么b對象會常駐內(nèi)存,直到程序終止。
          3. 盡量避免過多過常的創(chuàng)建Java對象
          盡量避免在經(jīng)常調(diào)用的方法,循環(huán)中new對象,由于系統(tǒng)不僅要花費(fèi)時間來創(chuàng)建對象,而且還要花時間對這些對象進(jìn)行垃圾回收和處理,在我們可以控制的范圍內(nèi),最大限度的重用對象,最好能用基本的數(shù)據(jù)類型或數(shù)組來替代對象。
          4. 盡量使用final修飾符
          帶有final修飾符的類是不可派生的。在Java核心API中,有許多應(yīng)用final的例子,例如java.lang.String。為String類指定final防止了使用者覆蓋length()方法。另外,如果一個類是final的,則該類所有方法都是final的。Java編譯器會尋找機(jī)會內(nèi)聯(lián)(inline)所有的final方法(這和具體的編譯器實現(xiàn)有關(guān))。此舉能夠使性能平均提高50%。
          5. 盡量使用局部變量
          調(diào)用方法時傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度較快。其他變量,如靜態(tài)變量、實例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。
          6. 盡量處理好包裝類型和基本類型兩者的使用場所
          雖然包裝類型和基本類型在使用過程中是可以相互轉(zhuǎn)換,但它們兩者所產(chǎn)生的內(nèi)存區(qū)域是完全不同的,基本類型數(shù)據(jù)產(chǎn)生和處理都在棧中處理,包裝類型是對象,是在堆中產(chǎn)生實例。
          在集合類對象,有對象方面需要的處理適用包裝類型,其他的處理提倡使用基本類型。
          7. 慎用synchronized,盡量減小synchronize的方法
          都知道,實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。synchronize方法被調(diào)用時,直接會把當(dāng)前對象鎖 了,在方法執(zhí)行完之前其他線程無法調(diào)用當(dāng)前對象的其他方法。所以synchronize的方法盡量小,并且應(yīng)盡量使用方法同步代替代碼塊同步。
          8. 盡量使用StringBuilder和StringBuffer進(jìn)行字符串連接
          這個就不多講了。
          9. 盡量不要使用finalize方法
          實際上,將資源清理放在finalize方法中完成是非常不好的選擇,由于GC的工作量很大,尤其是回收Young代內(nèi)存時,大都會引起應(yīng)用程序暫停,所以再選擇使用finalize方法進(jìn)行資源清理,會導(dǎo)致GC負(fù)擔(dān)更大,程序運(yùn)行效率更差。
          10. 盡量使用基本數(shù)據(jù)類型代替對象
          String str = "hello";
          上面這種方式會創(chuàng)建一個“hello”字符串,而且JVM的字符緩存池還會緩存這個字符串;
          String str = new String("hello");
          此時程序除創(chuàng)建字符串外,str所引用的String對象底層還包含一個char[]數(shù)組,這個char[]數(shù)組依次存放了h,e,l,l,o
          11. 單線程應(yīng)盡量使用HashMap、ArrayList
          HashTable、Vector等使用了同步機(jī)制,降低了性能。
          12. 盡量合理的創(chuàng)建HashMap
          當(dāng)你要創(chuàng)建一個比較大的hashMap時,充分利用另一個構(gòu)造函數(shù)
          public HashMap(int initialCapacity, float loadFactor)
          避免HashMap多次進(jìn)行了hash重構(gòu),擴(kuò)容是一件很耗費(fèi)性能的事,在默認(rèn)中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能準(zhǔn)確的估計你所需要的最佳大小,同樣的Hashtable,Vectors也是一樣的道理。
          13. 盡量減少對變量的重復(fù)計算
          for(int i=0;i<list.size();i++)
          應(yīng)該改為
          for(int i=0,len=list.size();i<len;i++)
          并且在循環(huán)中應(yīng)該避免使用復(fù)雜的表達(dá)式,在循環(huán)中,循環(huán)條件會被反復(fù)計算,如果不使用復(fù)雜表達(dá)式,而使循環(huán)條件值不變的話,程序?qū)\(yùn)行的更快。 
          14. 盡量避免不必要的創(chuàng)建
          A a = new A();
          if(i==1){list.add(a);}
          應(yīng)該改為
          if(i==1){
          A a = new A();
          list.add(a);}
          15. 盡量在finally塊中釋放資源
          程序中使用到的資源應(yīng)當(dāng)被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程序執(zhí)行的結(jié)果如何,finally塊總是會執(zhí)行的,以確保資源的正確關(guān)閉。 
          16. 盡量使用移位來代替'a/b'的操作
          "/"是一個代價很高的操作,使用移位的操作將會更快和更有效
          int num = a / 4;
          int num = a / 8;
          應(yīng)該改為
          int num = a >> 2;
          int num = a >> 3;
          但注意的是使用移位應(yīng)添加注釋,因為移位操作不直觀,比較難理解
          17.盡量使用移位來代替'a*b'的操作
          同樣的,對于'*'操作,使用移位的操作將會更快和更有效
          int num = a * 4;
          int num = a * 8;
          應(yīng)該改為
          int num = a << 2;
          int num = a << 3;
          18. 盡量確定StringBuffer的容量
          StringBuffer 的構(gòu)造器會創(chuàng)建一個默認(rèn)大小(通常是16)的字符數(shù)組。在使用中,如果超出這個大小,就會重新分配內(nèi)存,創(chuàng)建一個更大的數(shù)組,并將原先的數(shù)組復(fù)制過來,再 丟棄舊的數(shù)組。在大多數(shù)情況下,你可以在創(chuàng)建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。 
          如:StringBuffer buffer = new StringBuffer(1000);  
          19. 盡量早釋放無用對象的引用
          大部分時,方法局部引用變量所引用的對象 會隨著方法結(jié)束而變成垃圾,因此,大部分時候程序無需將局部,引用變量顯式設(shè)為null。
          例如:
          Java代碼
          1. Public void test(){   
          2. Object obj = new Object();   
          3. ……   
          4. Obj=null;   
          5. }  
          Public void test(){ Object obj = new Object(); …… Obj=null; }
           
          上面這個就沒必要了,隨著方法test()的執(zhí)行完成,程序中obj引用變量的作用域就結(jié)束了。但是如果是改成下面:
          Java代碼
          1. Public void test(){   
          2. Object obj = new Object();   
          3. ……   
          4. Obj=null;   
          5. //執(zhí)行耗時,耗內(nèi)存操作;或調(diào)用耗時,耗內(nèi)存的方法   
          6. ……   
          7. }  
          Public void test(){ Object obj = new Object(); …… Obj=null; //執(zhí)行耗時,耗內(nèi)存操作;或調(diào)用耗時,耗內(nèi)存的方法 …… }
           
          這時候就有必要將obj賦值為null,可以盡早的釋放對Object對象的引用。
          20. 盡量避免使用二維數(shù)組
          二維數(shù)據(jù)占用的內(nèi)存空間比一維數(shù)組多得多,大概10倍以上。
          21. 盡量避免使用split
          除非是必須的,否則應(yīng)該避免使用split,split由于支持正則表達(dá)式,所以效率比較低,如果是頻繁的幾十,幾百萬的調(diào)用將會耗費(fèi)大量資源,如果確實需 要頻繁的調(diào)用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結(jié)果。
          22. ArrayList & LinkedList
          一 個是線性表,一個是鏈表,一句話,隨機(jī)查詢盡量使用ArrayList,ArrayList優(yōu)于LinkedList,LinkedList還要移動指 針,添加刪除的操作LinkedList優(yōu)于ArrayList,ArrayList還要移動數(shù)據(jù),不過這是理論性分析,事實未必如此,重要的是理解好2 者得數(shù)據(jù)結(jié)構(gòu),對癥下藥。
          23. 盡量使用System.arraycopy ()代替通過來循環(huán)復(fù)制數(shù)組
          System.arraycopy() 要比通過循環(huán)來復(fù)制數(shù)組快的多 
          24. 盡量緩存經(jīng)常使用的對象
          盡可能將經(jīng)常使用的對象進(jìn)行緩存,可以使用數(shù)組,或HashMap的容器來進(jìn)行緩存,但這種方式可能導(dǎo)致系統(tǒng)占用過多的緩存,性能下降,推薦可以使用一些第三方的開源工具,如EhCache,Oscache進(jìn)行緩存,他們基本都實現(xiàn)了FIFO/FLU等緩存算法。
          25. 盡量避免非常大的內(nèi)存分配
          有時候問題不是由當(dāng)時的堆狀態(tài)造成的,而是因為分配失敗造成的。分配的內(nèi)存塊都必須是連續(xù)的,而隨著堆越來越滿,找到較大的連續(xù)塊越來越困難。
          26. 慎用異常
          當(dāng)創(chuàng)建一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用于描述異常是在何處創(chuàng)建的。構(gòu)建這些棧跟蹤時需要為運(yùn)行時棧做一份快照,正是這一部分開銷很大。當(dāng)需要創(chuàng)建一個 Exception 時,JVM 不得不說:先別動,我想就您現(xiàn)在的樣子存一份快照,所以暫時停止入棧和出棧操作。棧跟蹤不只包含運(yùn)行時棧中的一兩個元素,而是包含這個棧中的每一個元素。
          如 果您創(chuàng)建一個 Exception ,就得付出代價。好在捕獲異常開銷不大,因此可以使用 try-catch 將核心內(nèi)容包起來。從技術(shù)上講,您甚至可以隨意地拋出異常,而不用花費(fèi)很大的代價。招致性能損失的并不是 throw 操作——盡管在沒有預(yù)先創(chuàng)建異常的情況下就拋出異常是有點不尋常。真正要花代價的是創(chuàng)建異常。幸運(yùn)的是,好的編程習(xí)慣已教會我們,不應(yīng)該不管三七二十一就 拋出異常。異常是為異常的情況而設(shè)計的,使用時也應(yīng)該牢記這一原則。

          相關(guān)回復(fù):
          xuanyuan 寫道
          7.慎用synchronized,盡量減小synchronize的方法
          re:同意,不過文中有個地方說錯了,使用synchronized關(guān)鍵字并不一定都是鎖定當(dāng)前對象的,要看具體的鎖是什么。如果是在方法上加的synchronized,則是以對象本身為鎖的,如果是靜態(tài)方法則鎖的粒度是類。
          ---------------
          9.盡量不要使用finalize方法
          re:同意,其實不推薦用finalize方法的根本原因在于,JVM的規(guī)范并不保證何時執(zhí)行該方法,所以用這個方法來釋放資源很不合適,有可能造成長時間資源得不到釋放。
          ---------------
          16.盡量使用移位來代替'a/b'的操作;17.盡量使用移位來代替'a*b'的操作
          re:個人不太同意這兩條。這樣做確實有更好的性能,但是卻犧牲了可讀性。這兩個操作符對很多程序員來說并不直觀。我認(rèn)為在如今硬件價格不那么昂貴的情況下,略微犧牲一些性能,換來更好的可讀性和可維護(hù)性是好的選擇。
           
          wuzhengju 寫道
          19.盡量早釋放無用對象的引用
          大部分時,方法局部引用變量所引用的對象 會隨著方法結(jié)束而變成垃圾,因此,大部分時候程序無需將局部,引用變量顯式設(shè)為null。
          例如:
          Public void test(){
          Object obj = new Object();
          ……
          Obj=null;
          }
          上面這個就沒必要了,隨著方法test()的執(zhí)行完成,程序中obj引用變量的作用域就結(jié)束了。但是如果是改成下面:
          Public void test(){
          Object obj = new Object();
          ……
          Obj=null;
          //執(zhí)行耗時,耗內(nèi)存操作;或調(diào)用耗時,耗內(nèi)存的方法
          ……
          }
          如果Object obj = new Object(); 如果這對象并不是大對象,這有必要嗎?Obj=null;只是告訴jvm這個對象已經(jīng)成為垃圾,至于什么時候回收,還不能確定! 這可讀性也不好!
          posted @ 2012-04-16 14:49 甜咖啡 閱讀(207) | 評論 (0)編輯 收藏

          下面的代碼片段是由經(jīng)過驗證的程序修改而來。觀察這些代碼片段你會發(fā)現(xiàn),跟以前的版本相比,在Java7里,文件相關(guān)的操作變得簡單的多了。通過使用新的Files類里提供的各種方法,你可以只用一行代碼就能完成下列的文件操作:

          • 創(chuàng)建文件
          • 刪除文件
          • 復(fù)制文件
          • 文件移動/改名

          這篇文件是以你對Java7里提供的新的Path類很熟悉為前提,如果你不熟悉這個類,這里就簡單說一句,Path是文件系統(tǒng)里對位置的一個邏輯概念,例如c:\ 和../foobar.txt都是Path。

          創(chuàng)建和刪除文件

          下面的代碼片段向你展示的是用 Files.createFile (Path target) 方法創(chuàng)建文件的基本用法。

          1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
            Path file = Files.createFile (target);  

          很多時候,出于安全的原因,你可能希望在創(chuàng)建的文件上設(shè)置一下屬性,例如:是否可讀/可寫/寫執(zhí)行。這些屬性依賴于文件系統(tǒng)的種類,你需要使用跟文件系統(tǒng)相應(yīng)的權(quán)限輔助類來完成這種操作。例如,PosixFilePermission和PosixFilePermissions為POSIX文件系統(tǒng)設(shè)計的。下面的是在POSIX文件系統(tǒng)上的文件設(shè)置讀寫權(quán)限的用法。

          1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
            Set<PosixFilePermission> perms = PosixFilePermissions.fromString ("rw-rw-rw-");
            FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute (perms);
            Files.createFile (target, attr);

          這個java.nio.file.attribute包里提供了很多關(guān)于FilePermission的類。

          警告當(dāng)創(chuàng)建一個帶有權(quán)限屬性的文件時,請注意包含這個文件的文件夾是否有權(quán)限的強(qiáng)制約束。例如,你會發(fā)現(xiàn),由于這些限制,盡管你給創(chuàng)建的文件指定了rw-rw-rw權(quán)限,實際創(chuàng)建的結(jié)果卻是rw-r–r–。

          刪除文件更簡單,使用Files.delete (Path)這個方法。

          1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
            Files.delete (target);  

          拷貝和移動文件

          下面的代碼向你展示的是使用Files.copy (Path source, Path target)方法做文件拷貝的基本用法。

          1. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
          2. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
            Files.copy (source, target);  

          經(jīng)常的,在拷貝文件的過程中你可能希望指定一些操作設(shè)置。在Java7里,你可以通過使用StandardCopyOption enum來設(shè)置這些屬性。下面看一個例子。

          1. import static java.nio.file.StandardCopyOption.*;  
          2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
          3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
          4. Files.copy (source, target, REPLACE_EXISTING);  

          拷貝操作時可以使用的屬性還包括COPY_ATTRIBUTES (保留文件屬性) 和ATOMIC_MOVE (確保移動事務(wù)操作的成功,否則進(jìn)行回滾)。

          移動文件的操作跟拷貝很相似,使用Files.move (Path source, Path target)方法。

          同樣,你也可以指定移動操作的屬性,使用Files.move (Path source, Path target, CopyOptions...) 方法里的參數(shù)來設(shè)置。

          1. import static java.nio.file.StandardCopyOption.*;  
          2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
          3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
            Files.move (source, target, REPLACE_EXISTING,COPY_ATTRIBUTES);  

          可以看出,新的用于文件操作的NIO.2 API 非常便于使用。

          posted @ 2012-04-16 10:25 甜咖啡 閱讀(237) | 評論 (0)編輯 收藏

          眾所周知,隨機(jī)數(shù)是任何一種編程語言最基本的特征之一。而生成隨機(jī)數(shù)的基本方式也是相同的:產(chǎn)生一個0到1之間的隨機(jī)數(shù)。看似簡單,但有時我們也會忽略了一些有趣的功能。

          我們從書本上學(xué)到什么?

          最明顯的,也是直觀的方式,在Java中生成隨機(jī)數(shù)只要簡單的調(diào)用:

          1. java.lang.Math.random() 

          在所有其他語言中,生成隨機(jī)數(shù)就像是使用Math工具類,如abs, pow, floor, sqrt和其他數(shù)學(xué)函數(shù)。大多數(shù)人通過書籍、教程和課程來了解這個類。一個簡單的例子:從0.0到1.0之間可以生成一個雙精度浮點數(shù)。那么通過上面的信息,開發(fā)人員要產(chǎn)生0.0和10.0之間的雙精度浮點數(shù)會這樣來寫:

          1. Math.random() * 10 

          而產(chǎn)生0和10之間的整數(shù),則會寫成:

          1. Math.round(Math.random() * 10) 

          進(jìn)階

          通過閱讀Math.random()的源碼,或者干脆利用IDE的自動完成功能,開發(fā)人員可以很容易發(fā)現(xiàn),java.lang.Math.random()使用一個內(nèi)部的隨機(jī)生成對象 - 一個很強(qiáng)大的對象可以靈活的隨機(jī)產(chǎn)生:布爾值、所有數(shù)字類型,甚至是高斯分布。例如:

          1. new java.util.Random().nextInt(10) 

          它有一個缺點,就是它是一個對象。它的方法必須是通過一個實例來調(diào)用,這意味著必須先調(diào)用它的構(gòu)造函數(shù)。如果在內(nèi)存充足的情況下,像上面的表達(dá)式是可以接受的;但內(nèi)存不足時,就會帶來問題。

          一個簡單的解決方案,可以避免每次需要生成一個隨機(jī)數(shù)時創(chuàng)建一個新實例,那就是使用一個靜態(tài)類。猜你可能想到了java.lang.Math,很好,我們就是改良java.lang.Math的初始化。雖然這個工程量低,但你也要做一些簡單的單元測試來確保其不會出錯。

          假設(shè)程序需要生成一個隨機(jī)數(shù)來存儲,問題就又來了。比如有時需要操作或保護(hù)種子(seed),一個內(nèi)部數(shù)用來存儲狀態(tài)和計算下一個隨機(jī)數(shù)。在這些特殊情況下,共用隨機(jī)生成對象是不合適的。

          并發(fā)

          在Java EE多線程應(yīng)用程序的環(huán)境中,隨機(jī)生成實例對象仍然可以被存儲在類或其他實現(xiàn)類,作為一個靜態(tài)屬性。幸運(yùn)的是,java.util.Random是線程安全的,所以不存在多個線程調(diào)用會破壞種子(seed)的風(fēng)險。

          另一個值得考慮的是多線程java.lang.ThreadLocal的實例。偷懶的做法是通過Java本身API實現(xiàn)單一實例,當(dāng)然你也可以確保每一個線程都有自己的一個實例對象。

          雖然Java沒有提供一個很好的方法來管理java.util.Random的單一實例。但是,期待已久的Java 7提供了一種新的方式來產(chǎn)生隨機(jī)數(shù):

          1. java.util.concurrent.ThreadLocalRandom.current().nextInt(10) 

          這個新的API綜合了其他兩種方法的優(yōu)點:單一實例/靜態(tài)訪問,就像Math.random()一樣靈活。ThreadLocalRandom也比其他任何處理高并發(fā)的方法要更快。

          經(jīng)驗

          Chris Marasti-Georg 指出:

          1. Math.round(Math.random() * 10) 

          使分布不平衡,例如:0.0 - 0.499999將四舍五入為0,而0.5至1.499999將四舍五入為1。那么如何使用舊式語法來實現(xiàn)正確的均衡分布,如下:

          1. Math.floor(Math.random() * 11) 

          幸運(yùn)的是,如果我們使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用擔(dān)心上述問題了。

          Java實戰(zhàn)項目里面介紹了一些不正確使用java.util.Random API的危害。這個教訓(xùn)告訴我們不要使用:

          1. Math.abs(rnd.nextInt())%n 

          而使用:

          1. rnd.nextInt(n) 
          posted @ 2012-04-16 10:01 甜咖啡 閱讀(187) | 評論 (0)編輯 收藏
          package com.wss;

          import java.io.File;
          import java.util.ArrayList;
          import java.util.List;
          import java.util.UUID;

          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;
          import javax.xml.transform.Transformer;
          import javax.xml.transform.TransformerFactory;
          import javax.xml.transform.dom.DOMSource;
          import javax.xml.transform.stream.StreamResult;

          import org.w3c.dom.Document;
          import org.w3c.dom.Element;
          import org.w3c.dom.Node;
          import org.w3c.dom.NodeList;
          import org.w3c.dom.Text;

          public class GPS_GNSS_XML_Color {
              //刪除節(jié)點時傳入的參數(shù)
              private static String deleteNumber;
              
              //修改節(jié)點時傳入的參數(shù)
              private static String updateNumber;
              
              //讀取傳入的路徑,返回一個document對象
              public static Document loadInit(String filePath){
                  Document document = null;
                  try{
                      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                      DocumentBuilder builder = factory.newDocumentBuilder();
                      document = builder.parse(new File(filePath));
                      document.normalize();
                      return document;
                  }catch(Exception e){
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return null;
                  }
              }

              /**
               * 刪除制定的xml
               * @param filePath
               * @return
               */
              public static boolean deleteXML(String filePath){
                  deleteNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
                  Document document = loadInit(filePath);
                  try{
                      NodeList nodeList = document.getElementsByTagName("color");
                      for(int i=0; i<nodeList.getLength(); i++){
                          String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                          //刪除節(jié)點時傳入的參數(shù)
                          if(number_.equals(deleteNumber)){
                              Node node = nodeList.item(i);
                              node.getParentNode().removeChild(node);
                              saveXML(document, filePath);
                          }
                      }
                      return true;
                  }catch(Exception e){
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return false;
                  }
              }
              
              /**
               * 修改制定的xml
               * @param filePath
               * @return
               */
              public static boolean updateXML(String filePath){
                  updateNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
                   //讀取傳入的路徑,返回一個document對象
                   Document document = loadInit(filePath);
                   try{
                      //獲取葉節(jié)點
                       NodeList nodeList = document.getElementsByTagName("color");
                      //遍歷葉節(jié)點
                       for(int i=0; i<nodeList.getLength(); i++){
                           String number = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                           String colorValue = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                           Double minValue = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                           Double maxValue = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                           //修改節(jié)點時傳入的參數(shù)
                           if(number.equals(updateNumber)){
                               document.getElementsByTagName("colorValue").item(i).getFirstChild().setNodeValue("black");
                               document.getElementsByTagName("minValue").item(i).getFirstChild().setNodeValue("2222");
                               document.getElementsByTagName("maxValue").item(i).getFirstChild().setNodeValue("22222");
                               System.out.println();
                           }
                       }
                       saveXML(document, filePath);
                       return true;
                   }catch(Exception e){
                       e.printStackTrace();
                       System.out.println(e.getMessage());
                       return false;
                   }
              }
              
              /**
               * 添加節(jié)點
               * @param filePath
               * @return
               */
              public static boolean addXML(String filePath){
                  try{
                      //讀取傳入的路徑,返回一個document對象
                      Document document = loadInit(filePath);
                      //創(chuàng)建葉節(jié)點
                      Element eltColor = document.createElement("color");
                      Element eltNumber = document.createElement("number");//創(chuàng)建葉節(jié)點的第一個元素
                      Element eltColorValue = document.createElement("colorValue");//創(chuàng)建葉節(jié)點的第二個元素
                      Element eltMinValue = document.createElement("minValue");//創(chuàng)建葉節(jié)點的第三個元素
                      Element eltMaxValue = document.createElement("maxValue");//創(chuàng)建葉節(jié)點的第四個元素
                      Text number_ = document.createTextNode(UUID.randomUUID().toString());//創(chuàng)建葉節(jié)點的第一個元素下的文本節(jié)點
                      eltNumber.appendChild(number_);//把該文本節(jié)點加入到葉節(jié)點的第一個元素里面
                      Text colorValue_ = document.createTextNode("colorValue");//創(chuàng)建葉節(jié)點的第二個元素下的文本節(jié)點
                      eltColorValue.appendChild(colorValue_);//把該文本節(jié)點加入到葉節(jié)點的第二個元素里面
                      Text minValue_ = document.createTextNode("100");//創(chuàng)建葉節(jié)點的第三個元素下的文本節(jié)點
                      eltMinValue.appendChild(minValue_);//把該文本節(jié)點加入到葉節(jié)點的第三個元素里面
                      Text maxValue_ = document.createTextNode("200");//創(chuàng)建葉節(jié)點的第四個元素下的文本節(jié)點
                      eltMaxValue.appendChild(maxValue_);//把該文本節(jié)點加入到葉節(jié)點的第四個元素里面
                      //把葉節(jié)點下的元素加入到葉節(jié)點下
                      eltColor.appendChild(eltNumber);
                      eltColor.appendChild(eltColorValue);
                      eltColor.appendChild(eltMinValue);
                      eltColor.appendChild(eltMaxValue);
                      //獲取根節(jié)點
                      Element eltRoot = document.getDocumentElement();
                      //把葉節(jié)點加入到根節(jié)點下
                      eltRoot.appendChild(eltColor);
                      //更新修改后的源文件
                      saveXML(document, filePath);
                      return true;
                  }catch(Exception e){
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return false;
                  }
              }
              
              /**
               * 把修改后的document寫進(jìn)源文件(更新源文件)
               * @param document
               * @param filePath
               * @return
               */
              public static boolean saveXML(Document document, String filePath){
                  try{
                      TransformerFactory tFactory = TransformerFactory.newInstance();
                      Transformer transformer = tFactory.newTransformer();
                      
                      DOMSource source = new DOMSource(document);
                      StreamResult result = new StreamResult(new File(filePath));
                      transformer.transform(source, result);
                      return true;
                  }catch(Exception e){
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return false;
                  }
              }
              
              /**
               * 獲取xml文件的所有記錄
               * @param filePath
               * @return
               */
              public static List<ColorValue> selectXML(String filePath){
                   List<ColorValue> colorValueList = new ArrayList<ColorValue>();
                   try{
                       //讀取傳入的路徑,返回一個document對象
                       Document document = loadInit(filePath);
                       //獲取葉節(jié)點
                       NodeList nodeList = document.getElementsByTagName("color");
                       //遍歷葉節(jié)點
                       for(int i=0; i<nodeList.getLength(); i++){
                           ColorValue colorValue = new ColorValue();
                           String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                           String colorValue_ = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                           Double minValue_ = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                           Double maxValue_ = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                           colorValue.setNumber(number_);
                           colorValue.setColorValue(colorValue_);
                           colorValue.setMinValue(minValue_);
                           colorValue.setMaxValue(maxValue_);
                           colorValueList.add(colorValue);
                       }
                       return colorValueList;
                   }catch(Exception e){
                       e.printStackTrace();
                       System.out.println(e.getMessage());
                       return null;
                   }
              }
          }






          package com.wss;

          public class ColorValue {

              private String number;
              private String colorValue;
              private Double minValue;
              private Double maxValue;
              public String getNumber() {
                  return number;
              }
              public void setNumber(String number) {
                  this.number = number;
              }
              public String getColorValue() {
                  return colorValue;
              }
              public void setColorValue(String colorValue) {
                  this.colorValue = colorValue;
              }
              public Double getMinValue() {
                  return minValue;
              }
              public void setMinValue(Double minValue) {
                  this.minValue = minValue;
              }
              public Double getMaxValue() {
                  return maxValue;
              }
              public void setMaxValue(Double maxValue) {
                  this.maxValue = maxValue;
              }
          }



          <?xml version="1.0" encoding="UTF-8" standalone="no"?>
          <Colors>
              <color>
                  <number>7007b384-fab3-4779-9171-229d0664b6b5</number>
                  <colorValue>black</colorValue>
                  <minValue>2222</minValue>
                  <maxValue>22222</maxValue>
              </color>
              <color>
                  <number>421f481e-790c-41be-91e3-27d215b73ce2</number>
                  <colorValue>colorValue</colorValue>
                  <minValue>100</minValue>
                  <maxValue>200</maxValue>
              </color>
          </Colors>
          posted @ 2011-11-08 21:56 甜咖啡 閱讀(9571) | 評論 (1)編輯 收藏

           

                  // 寫文件UTF-8格式 寫一行
            public static void writerTxtFile(String filePath, String text) {
            OutputStreamWriter fs;
            try {
            fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
            fs.write(text + "\n");
            fs.flush();
            fs.close();
            } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            } catch (IOException e) {
            e.printStackTrace();
            }
            }
           
            // 寫文件UTF-8格式 寫一行
            public static void writerStringBuffer(String filePath, StringBuffer text) {
            OutputStreamWriter fs;
            try {
            fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
            fs.write(text + "\n");
            fs.flush();
            fs.close();
            } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            } catch (IOException e) {
            e.printStackTrace();
            }
            }
           
            // 寫文件
            public static void writerTxtFile(String filePath, List<String> list) {
            OutputStreamWriter fs;
            try {
            fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
            for(int i=0; i<list.size(); i++){
            fs.write(list.get(i) + "\n");
            }
            fs.flush();
            fs.close();
            } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            } catch (IOException e) {
            e.printStackTrace();
            }
            }

           

          posted @ 2011-11-04 12:33 甜咖啡 閱讀(223) | 評論 (0)編輯 收藏

          package dateapp;

          import java.util.Date;
          import java.util.Calendar;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.text.ParseException;
          import java.awt.Color;
          import java.awt.Font;
          import java.awt.Point;
          import java.awt.Dimension;
          import java.awt.BorderLayout;
          import java.awt.FlowLayout;
          import java.awt.GridLayout;
          import java.awt.Component;
          import java.awt.Cursor;
          import java.awt.Frame;

          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;
          import java.awt.event.MouseListener;
          import java.awt.event.MouseAdapter;
          import java.awt.event.MouseEvent;
          //import javax.swing.JFrame;
          import javax.swing.JButton;
          import javax.swing.JComboBox;
          import javax.swing.JDialog;
          import javax.swing.JPanel;
          import javax.swing.JLabel;
          import javax.swing.JSpinner;
          import javax.swing.JSpinner.NumberEditor;
          import javax.swing.SpinnerNumberModel;
          import javax.swing.SwingUtilities;
          import javax.swing.SwingConstants;
          import javax.swing.event.ChangeListener;
          import javax.swing.event.ChangeEvent;
          import javax.swing.border.LineBorder;

          public class DateChooseJButton extends JButton {

           private DateChooser dateChooser = null;

           private String preLabel = "";

           public DateChooseJButton() {
            this(getNowDate());
           }

           public DateChooseJButton(SimpleDateFormat df, String dateString) {
            this();
            setText(df, dateString);
           }

           public DateChooseJButton(Date date) {
            this("", date);
           }

           public DateChooseJButton(String preLabel, Date date) {
            if (preLabel != null)
             this.preLabel = preLabel;
            setDate(date);
            setBorder(null);
            setCursor(new Cursor(Cursor.HAND_CURSOR));
            super.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
              if (dateChooser == null)
               dateChooser = new DateChooser();
              Point p = getLocationOnScreen();
              p.y = p.y + 30;
              dateChooser.showDateChooser(p);
             }
            });
           }

           private static Date getNowDate() {
            return Calendar.getInstance().getTime();
           }

           private static SimpleDateFormat getDefaultDateFormat() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           }

           // 覆蓋父類的方法
           public void setText(String s) {
            Date date;
            try {
             date = getDefaultDateFormat().parse(s);
            } catch (ParseException e) {
             date = getNowDate();
            }
            setDate(date);
           }

           public void setText(SimpleDateFormat df, String s) {
            Date date;
            try {
             date = df.parse(s);
            } catch (ParseException e) {
             date = getNowDate();
            }
            setDate(date);
           }

           public void setDate(Date date) {
            super.setText(preLabel + getDefaultDateFormat().format(date));
           }

           public Date getDate() {
            String dateString = getText().substring(preLabel.length());
            try {
             return getDefaultDateFormat().parse(dateString);
            } catch (ParseException e) {
             return getNowDate();
            }

           }

           // 覆蓋父類的方法使之無效
           public void addActionListener(ActionListener listener) {
           }

           private class DateChooser extends JPanel implements ActionListener,
             ChangeListener {
            int startYear = 1980; // 默認(rèn)【最小】顯示年份
            int lastYear = 2050; // 默認(rèn)【最大】顯示年份
            int width = 400; // 界面寬度
            int height = 200; // 界面高度

            Color backGroundColor = Color.gray; // 底色
            // 月歷表格配色----------------//
            Color palletTableColor = Color.white; // 日歷表底色
            Color todayBackColor = Color.orange; // 今天背景色
            Color weekFontColor = Color.blue; // 星期文字色
            Color dateFontColor = Color.black; // 日期文字色
            Color weekendFontColor = Color.red; // 周末文字色

            // 控制條配色------------------//
            Color controlLineColor = Color.pink; // 控制條底色
            Color controlTextColor = Color.white; // 控制條標(biāo)簽文字色

            Color rbFontColor = Color.white; // RoundBox文字色
            Color rbBorderColor = Color.red; // RoundBox邊框色
            Color rbButtonColor = Color.pink; // RoundBox按鈕色
            Color rbBtFontColor = Color.red; // RoundBox按鈕文字色

            JDialog dialog;
            JSpinner yearSpin;
            JSpinner monthSpin;
            JSpinner hourSpin;
            JComboBox minSpin;
            JComboBox secondBox;
            JButton[][] daysButton = new JButton[6][7];

            DateChooser() {

             setLayout(new BorderLayout());
             setBorder(new LineBorder(backGroundColor, 2));
             setBackground(backGroundColor);

             JPanel topYearAndMonth = createYearAndMonthPanal();
             add(topYearAndMonth, BorderLayout.NORTH);
             JPanel centerWeekAndDay = createWeekAndDayPanal();
             add(centerWeekAndDay, BorderLayout.CENTER);

            }

            private JPanel createYearAndMonthPanal() {

             Calendar c = getCalendar();
             int currentYear = c.get(Calendar.YEAR);
             int currentMonth = c.get(Calendar.MONTH) + 1;
             int currentHour = c.get(Calendar.HOUR_OF_DAY);
             int currentMin = c.get(Calendar.MINUTE);
             int currentSecond = c.get(Calendar.SECOND);

             JPanel result = new JPanel();
             result.setLayout(new FlowLayout());
             result.setBackground(controlLineColor);

             yearSpin = new JSpinner(new SpinnerNumberModel(currentYear,
               startYear, lastYear, 1));
             yearSpin.setPreferredSize(new Dimension(48, 20));
             yearSpin.setName("Year");
             yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
             yearSpin.addChangeListener(this);
             result.add(yearSpin);

             JLabel yearLabel = new JLabel("年");
             yearLabel.setForeground(controlTextColor);
             result.add(yearLabel);

             monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1,
               12, 1));
             monthSpin.setPreferredSize(new Dimension(35, 20));
             monthSpin.setName("Month");
             monthSpin.addChangeListener(this);
             result.add(monthSpin);

             JLabel monthLabel = new JLabel("月");
             monthLabel.setForeground(controlTextColor);
             result.add(monthLabel);

             hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23,
               1));
             hourSpin.setPreferredSize(new Dimension(35, 20));
             hourSpin.setName("Hour");
             hourSpin.addChangeListener(this);
             result.add(hourSpin);

             JLabel hourLabel = new JLabel("時");
             hourLabel.setForeground(controlTextColor);
             result.add(hourLabel);

             minSpin = new JComboBox();
             ;
             addComboBoxItem(minSpin);
             minSpin.setPreferredSize(new Dimension(45, 20));
             minSpin.setName("Min");
             minSpin.addItemListener(new java.awt.event.ItemListener() {
              public void itemStateChanged(java.awt.event.ItemEvent e) {
               JComboBox source = (JComboBox) e.getSource();
               Calendar c = getCalendar();
               if (source.getName().equals("Min")) {
                c.set(Calendar.MINUTE, getSelectedMin());
                setDate(c.getTime());
                return;
               }
              }
             });
             result.add(minSpin);

             JLabel minLabel = new JLabel("分");
             hourLabel.setForeground(controlTextColor);
             result.add(minLabel);

             secondBox = new JComboBox();
             addComboBoxItem(secondBox);
             secondBox.setPreferredSize(new Dimension(45, 20));
             secondBox.setName("Second");
             // secondBox.addActionListener(this) ;
             secondBox.addItemListener(new java.awt.event.ItemListener() {
              public void itemStateChanged(java.awt.event.ItemEvent e) {
               JComboBox source = (JComboBox) e.getSource();
               Calendar c = getCalendar();
               if (source.getName().equals("Second")) {
                c.set(Calendar.SECOND, getSelectedSecond());
                setDate(c.getTime());
                return;
               }
              }
             });

             result.add(secondBox);

             JLabel secondLabel = new JLabel("秒");
             hourLabel.setForeground(controlTextColor);
             result.add(secondLabel);

             return result;
            }

            private void addComboBoxItem(JComboBox comboBox) {
             for (int i = 0; i < 60; i++) {
              comboBox.addItem(i);
             }

            }

            private JPanel createWeekAndDayPanal() {
             String colname[] = { "日", "一", "二", "三", "四", "五", "六" };
             JPanel result = new JPanel();
             // 設(shè)置固定字體,以免調(diào)用環(huán)境改變影響界面美觀
             result.setFont(new Font("宋體", Font.PLAIN, 12));
             result.setLayout(new GridLayout(7, 7));
             result.setBackground(Color.white);
             JLabel cell;

             for (int i = 0; i < 7; i++) {
              cell = new JLabel(colname[i]);
              cell.setHorizontalAlignment(JLabel.RIGHT);
              if (i == 0 || i == 6)
               cell.setForeground(weekendFontColor);
              else
               cell.setForeground(weekFontColor);
              result.add(cell);
             }

             int actionCommandId = 0;
             for (int i = 0; i < 6; i++)
              for (int j = 0; j < 7; j++) {
               JButton numberButton = new JButton();
               numberButton.setBorder(null);
               numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
               numberButton.setActionCommand(String
                 .valueOf(actionCommandId));
               numberButton.addActionListener(this);
               numberButton.setBackground(palletTableColor);
               numberButton.setForeground(dateFontColor);
               if (j == 0 || j == 6)
                numberButton.setForeground(weekendFontColor);
               else
                numberButton.setForeground(dateFontColor);
               daysButton[i][j] = numberButton;
               result.add(numberButton);
               actionCommandId++;
              }

             return result;
            }

            private JDialog createDialog(Frame owner) {
             JDialog result = new JDialog(owner, "日期時間選擇", true);
             result.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
             result.getContentPane().add(this, BorderLayout.CENTER);
             result.pack();
             result.setSize(width, height);
             return result;
            }

            void showDateChooser(Point position) {
             Frame owner = (Frame) SwingUtilities
               .getWindowAncestor(DateChooseJButton.this);
             if (dialog == null || dialog.getOwner() != owner)
              dialog = createDialog(owner);
             dialog.setLocation(getAppropriateLocation(owner, position));
             flushWeekAndDay();
             dialog.show();
            }

            Point getAppropriateLocation(Frame owner, Point position) {
             Point result = new Point(position);
             Point p = owner.getLocation();
             int offsetX = (position.x + width) - (p.x + owner.getWidth());
             int offsetY = (position.y + height) - (p.y + owner.getHeight());

             if (offsetX > 0) {
              result.x -= offsetX;
             }

             if (offsetY > 0) {
              result.y -= offsetY;
             }

             return result;

            }

            private Calendar getCalendar() {
             Calendar result = Calendar.getInstance();
             result.setTime(getDate());
             return result;
            }

            private int getSelectedYear() {
             return ((Integer) yearSpin.getValue()).intValue();
            }

            private int getSelectedMonth() {
             return ((Integer) monthSpin.getValue()).intValue();
            }

            private int getSelectedHour() {
             return ((Integer) hourSpin.getValue()).intValue();
            }

            private int getSelectedMin() {
             return (Integer) this.minSpin.getSelectedItem();
            }

            private int getSelectedSecond() {
             return (Integer) this.secondBox.getSelectedItem();
            }

            private void dayColorUpdate(boolean isOldDay) {
             Calendar c = getCalendar();
             int day = c.get(Calendar.DAY_OF_MONTH);
             c.set(Calendar.DAY_OF_MONTH, 1);
             int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
             int i = actionCommandId / 7;
             int j = actionCommandId % 7;
             if (isOldDay)
              daysButton[i][j].setForeground(dateFontColor);
             else
              daysButton[i][j].setForeground(todayBackColor);
            }

            private void flushWeekAndDay() {
             Calendar c = getCalendar();
             c.set(Calendar.DAY_OF_MONTH, 1);
             int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
             int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
             for (int i = 0; i < 6; i++) {
              for (int j = 0; j < 7; j++) {
               String s = "";
               if (dayNo >= 1 && dayNo <= maxDayNo)
                s = String.valueOf(dayNo);
               daysButton[i][j].setText(s);
               dayNo++;
              }
             }
             dayColorUpdate(false);
            }

            public void stateChanged(ChangeEvent e) {
             JSpinner source = (JSpinner) e.getSource();
             Calendar c = getCalendar();
             if (source.getName().equals("Hour")) {
              c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
              setDate(c.getTime());
              return;
             }

             dayColorUpdate(true);

             if (source.getName().equals("Year"))
              c.set(Calendar.YEAR, getSelectedYear());
             else
              // (source.getName().equals("Month"))
              c.set(Calendar.MONTH, getSelectedMonth() - 1);
             setDate(c.getTime());
             flushWeekAndDay();
            }

            public void actionPerformed(ActionEvent e) {
             JButton source = (JButton) e.getSource();
             if (source.getText().length() == 0)
              return;
             dayColorUpdate(true);
             source.setForeground(todayBackColor);
             int newDay = Integer.parseInt(source.getText());
             Calendar c = getCalendar();
             c.set(Calendar.DAY_OF_MONTH, newDay);
             setDate(c.getTime());
            }

           }

           public static void main(String[] args){
            new JButton();
           }
          }

          上述日期控件繼承JButton,使用時只要構(gòu)造出來JButton對象就行了。


          posted @ 2011-11-04 12:32 甜咖啡 閱讀(4462) | 評論 (1)編輯 收藏

          package com.wss;

          import java.awt.BorderLayout;

          public class SearchTest extends JFrame {

           /**
            *
            */
           private static final long serialVersionUID = 1L;
           private JPanel contentPane;
           private JTextField latitude;
           private JTextField longitude;
           private JTextField max;
           private JTextField min;
           private JTextField center;
           private JComboBox begin;
           private JComboBox end;
           private JTable table;
           private DefaultTableModel dm;
           /**
            * Launch the application.
            */
           public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
             public void run() {
              try {
               SearchTest frame = new SearchTest();
               frame.setVisible(true);
              } catch (Exception e) {
               e.printStackTrace();
              }
             }
            });
           }

           /**
            * Create the frame.
            */
           public SearchTest() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getToolkit();
            setSize(Toolkit.getDefaultToolkit().getScreenSize());
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            contentPane.setLayout(new BorderLayout(0, 0));
            setContentPane(contentPane);
            
            JPanel panel = new JPanel();
            contentPane.add(panel, BorderLayout.NORTH);
            
            JLabel label = new JLabel("緯度:");
            panel.add(label);
            
            latitude = new JTextField();
            panel.add(latitude);
            latitude.setColumns(10);
            
            JLabel label_1 = new JLabel("經(jīng)度:");
            panel.add(label_1);
            
            longitude = new JTextField();
            panel.add(longitude);
            longitude.setColumns(10);
            
            JLabel label_2 = new JLabel("時間:");
            panel.add(label_2);
            
            //獲取數(shù)據(jù)庫里的時間正序輸出
            List<GPSBean> list_ = BusinessSelect.selectTime("select distinct to_char(obvdatetime,'YYYY-mm-dd HH24:MI:SS') t from gps order by t asc");
            String[] time = new String[list_.size()];
            for(int a=0; a<list_.size(); a++){
             time[a] = list_.get(a).getTime();
            }
            begin = new JComboBox(time);
            panel.add(begin);
            
            JLabel label_3 = new JLabel("至");
            panel.add(label_3);
            
            end = new JComboBox(time);
            panel.add(end);
              
            JButton close = new DateChooseJButton();
            panel.add(close);
            
            //點擊事件
            search.addActionListener(new SearchTest_search_actionAdapter(this));
            
            JPanel panel_1 = new JPanel();
            contentPane.add(panel_1, BorderLayout.CENTER);
            
            String name[] = {"ID","時間","緯度","經(jīng)度","值"};
            String sql = "select * from gps order by id desc";
            List<GPSBean> list = BusinessSelect.selectGPS(sql);
            Object gpsValue[][] = new Object[list.size()][5];
            
            for(int i=0; i<list.size(); i++){
             GPSBean gpsBean = list.get(i);
             Object value[] =
              {
               gpsBean.getId(),
               gpsBean.getObvdateTime(),
               gpsBean.getLongitude(),
               gpsBean.getLatitude(),
               gpsBean.getTecvalue()
              };
             for(int j=0; j<value.length; j++){
              gpsValue[i][j] = value[j];
             }
            }
            
            dm = new DefaultTableModel(gpsValue, name);
            table = new JTable(dm);
            table.setPreferredScrollableViewportSize(new Dimension(800,600));
            
            JScrollPane scrollPane = new JScrollPane(table);
            panel_1.add(scrollPane);
            
            JPanel panel_s = new JPanel();
            contentPane.add(panel_s, BorderLayout.SOUTH);
            
            JLabel max_ = new JLabel("最大值:");
            panel_s.add(max_);
            
            max = new JTextField();
            panel_s.add(max);
            max.setColumns(10);
            
            JLabel min_ = new JLabel("最小值:");
            panel_s.add(min_);
            
            min = new JTextField();
            panel_s.add(min);
            min.setColumns(10);
            
            JLabel center_ = new JLabel("中值:");
            panel_s.add(center_);
            
            center = new JTextField();
            panel_s.add(center);
            center.setColumns(10);
           }
           
           public void search_actionPerformed(ActionEvent e){
            dm.setRowCount(0);
            String latitude_value = latitude.getText();
            String longitude_value = longitude.getText();
            
            String begin_value = begin.getSelectedItem().toString();
            String end_value = end.getSelectedItem().toString();
            
            String sql = "";
            
            if(latitude_value.equals("") && longitude_value.equals("")){
             sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-0) a, abs(longitude-0) b " +
               "from gps where obvdateTime>=TO_DATE('"+begin_value
              +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
              +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
            }else{
             sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-"
               +Double.parseDouble(latitude_value)
               +") a, abs(longitude-"+Double.parseDouble(longitude_value)
               +") b from gps where obvdateTime>=TO_DATE('"+begin_value
               +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
               +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
            }
            
            ResultSet rs = CommontDAO.selectFile(sql);
            Vector<Object> v;
            String time = "2011-02-28 00:00:00";
            List<GPSBean> gpsBeanList = new ArrayList<GPSBean>();
            try{
             while(rs.next()){
              if(time.equals(rs.getString(2)) || time == rs.getString(2)){
              }else{
               GPSBean gpsBean = new GPSBean();
               gpsBean.setId(Integer.parseInt(rs.getString(1)));
               gpsBean.setObvdateTime(rs.getString(2));
               gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
               gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
               gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
               gpsBeanList.add(gpsBean);
               
               time = rs.getString(2);
               v = new Vector<Object>();
               v.add(rs.getString(1));
               v.add(rs.getString(2));
               v.add(rs.getString(3));
               v.add(rs.getString(4));
               v.add(rs.getString(5));
               dm.addRow(v);
              }
             }
            }catch(Exception ex){
             ex.printStackTrace();
             System.out.println(ex.getMessage());
            }finally{
             CommontDAO.cloes(rs);
             Double tecValue[] = new Double[gpsBeanList.size()];
             for(int i=0; i<gpsBeanList.size(); i++){
              tecValue[i] = gpsBeanList.get(i).getTecvalue();
             }
             
             Double center_value = Sort.center(tecValue);
             Double max_value = Sort.max(tecValue);
             Double min_value = Sort.min(tecValue);
             
             
             max.setText(max_value+"");
             min.setText(min_value+"");
             center.setText(center_value+"");
            }
           }
          }
          class SearchTest_search_actionAdapter implements ActionListener {
           private SearchTest adaptee;

           SearchTest_search_actionAdapter(SearchTest adaptee) {
            this.adaptee = adaptee;
           }

           public void actionPerformed(ActionEvent e) {
            adaptee.search_actionPerformed(e);
           }
          }




          package com.wss;

          import java.io.File;
          import java.io.FileOutputStream;
          import java.io.OutputStream;
          import java.sql.*;
          import java.util.*;

          public class BusinessSelect {

           //根據(jù)sql查詢記錄
           public static List<GPSBean> selectGPS(String sql){
            ResultSet rs = null;
            List<GPSBean> list = new ArrayList<GPSBean>();
            try{
             rs = CommontDAO.selectFile(sql);
             while(rs.next()){
              GPSBean gpsBean = new GPSBean();
              gpsBean.setId(Integer.parseInt(rs.getString(1)));
              gpsBean.setObvdateTime(rs.getString(2));
              gpsBean.setLongitude(Double.parseDouble(rs.getString(3)));
              gpsBean.setLatitude(Double.parseDouble(rs.getString(4)));
              gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
              list.add(gpsBean);
          //    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
             } 
             return list;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
            }finally{
             CommontDAO.cloes(rs);
            }
           }
           
           //搜索(根據(jù)經(jīng)度和緯度查詢最近一點的記錄)
           public static List<GPSBean> selectGPS(Double latitude_, Double longitude_){
            ResultSet rs = null;
            List<GPSBean> list = new ArrayList<GPSBean>();
            try{
             //獲取比指定點大的最近的1個值
             String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a from gps order by a desc";
             rs = CommontDAO.selectFile(sql);
             while(rs.next()){
              System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
             }
             System.out.println("---------------------------------------------------------------------------");
             
             sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(longitude-"+longitude_+") b from gps order by b desc";
             rs = CommontDAO.selectFile(sql);
             while(rs.next()){
          //    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
              System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
             }
             System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
             
             sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps order by a asc, b asc";
             //重要
          //   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('2011-03-01 00:00:00','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('2011-03-01 02:00:00','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
             while(rs.next()){
          //    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
              System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
             }
             
             return list;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
            }finally{
             CommontDAO.cloes(rs);
            }
           }
           
           //搜索(根據(jù)經(jīng)度和緯度查詢最近一點的記錄)
           public static List<GPSBean> selectGPS(Double latitude_, Double longitude_, String begin, String end){
            ResultSet rs = null;
            List<GPSBean> list = new ArrayList<GPSBean>();
            String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('"+begin+"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end+"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
            rs = CommontDAO.selectFile(sql);
            String test = "";
            try{
             while(rs.next()){
              GPSBean gpsBean = new GPSBean();
              gpsBean.setId(Integer.parseInt(rs.getString(1)));
              gpsBean.setObvdateTime(rs.getString(2));
              gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
              gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
              gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
              list.add(gpsBean);
          //    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
          //    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
          //    test += rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7)+"\r\n";
             }
          //   File f = new File("D:/test.txt");
          //   OutputStream out = new FileOutputStream(f,true);
          //   out.write(test.getBytes());
             return list;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
            }finally{
             CommontDAO.cloes(rs);
            }
           }
           
           //獲取時間
           public static List<GPSBean> selectTime(String sql){
            ResultSet rs = null;
            List<GPSBean> list = new ArrayList<GPSBean>();
            try{
             rs = CommontDAO.selectFile(sql);
             while(rs.next()){
              GPSBean gpsBean = new GPSBean();
              gpsBean.setTime(rs.getString(1));
              list.add(gpsBean);
             } 
             return list;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
            }finally{
             CommontDAO.cloes(rs);
            }
           }
          }

           




          package com.wss;

          public class GPSBean {

           private int id;
           private String obvdateTime;
           private double longitude;
           private double latitude;
           private double tecvalue;
           private String time;
           public int getId() {
            return id;
           }
           public void setId(int id) {
            this.id = id;
           }
           public String getObvdateTime() {
            return obvdateTime;
           }
           public void setObvdateTime(String obvdateTime) {
            this.obvdateTime = obvdateTime;
           }
           public double getLongitude() {
            return longitude;
           }
           public void setLongitude(double longitude) {
            this.longitude = longitude;
           }
           public double getLatitude() {
            return latitude;
           }
           public void setLatitude(double latitude) {
            this.latitude = latitude;
           }
           public double getTecvalue() {
            return tecvalue;
           }
           public void setTecvalue(double tecvalue) {
            this.tecvalue = tecvalue;
           }
           public String getTime() {
            return time;
           }
           public void setTime(String time) {
            this.time = time;
           }
          }





          package com.wss;

          import java.sql.Connection;
          import java.sql.ResultSet;
          import java.sql.Statement;

          import com.db.DBConnectionManager;

          public class CommontDAO {

           private static DBConnectionManager dbcm = DBConnectionManager.getInstance();
           
           //insert語句(支持多條sql)
           public static boolean insertFile(String sql){
            Connection con = null;
            Statement st = null;
            try{
             con = dbcm.getConnection();
             st = con.createStatement();
             sql = sql.substring(0, sql.length()-1);
             String[] num = sql.split(";");
             for(int i=0; i<num.length; i++){
              st.addBatch(num[i]);
             }
             st.executeBatch();
             return true;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return false;
            }finally{
             close(con, st);
            }
           }

           //select語句(返回一個ResultSet)
           public static ResultSet selectFile(String sql){
            Connection con = null;
            Statement st = null;
            ResultSet rs = null;
            try{
             con = dbcm.getConnection();
             st = con.createStatement();
             rs = st.executeQuery(sql);
             return rs;
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return rs;
            }
           }

           public static void close(Connection con){
            try{
             if(con != null){
              con.close();
             }
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
            }
           }

           public static void close(Connection con, Statement st){
            try{
             if(st != null){
              st.close();
             }
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
            }
            close(con);
           }
           
           public static void close(Connection con, Statement st, ResultSet rs){
            try{
             if(rs != null){
              rs.close();
             }
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
            }
            close(con, st);
           }
           
           public static void cloes(ResultSet rs){
            try{
             if(rs != null){
              rs.close();
             }
            }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
            }
           }
          }






          package com.wss;

          public class Sort {

           //求最大值
           public static Double max(Double[] value){
            //把數(shù)組第一個值最為一個標(biāo)志
            Double num1 = value[0];
            //中間變量
            Double temp = 0.0;
            for(int i=1; i<value.length; i++){
             if(num1 < value[i]){
              temp = num1;
              num1 = value[i];
              value[i] = temp;
             }
            }
            return num1;
           }
           
           //求最小值
           public static Double min(Double[] value){
            //把數(shù)組第一個值最為一個標(biāo)志
            Double num1 = value[0];
            //中間變量
            Double temp = 0.0;
            for(int i=0; i<value.length; i++){
             if(num1 > value[i]){
              temp = num1;
              num1 = value[i];
              value[i] = temp;
             }
            }
            return num1;
           }
           
           //求中值
           public static Double center(Double[] value){
            Double temp = 0.0;
            //排序
            for(int i=0; i<value.length; i++){
             for(int j=i+1; j<value.length; j++){
              if(value[i] > value[j]){
               temp = value[j];
               value[j] = value[i];
               value[i] = temp;
              }
             }
            }
            //求中值所在的下標(biāo)位置
            int num = value.length/2;
            return value[num];
            
           }
           
           public static void main(String[] args){
            Double value[] = {4.0, 1.0, 2.0, 3.0};
            System.out.println(Sort.center(value));
           }
          }







          posted @ 2011-11-04 12:31 甜咖啡 閱讀(1602) | 評論 (0)編輯 收藏
          DWR(Direct Web Remoting)是一個WEB遠(yuǎn)程調(diào)用框架.利用這個框架可以讓AJAX開發(fā)變得很簡單.利用DWR可以在客戶端利用JavaScript直接調(diào)用服務(wù)端的Java方法并返回值給JavaScript就好像直接本地客戶端調(diào)用一樣(DWR根據(jù)Java類來動態(tài)生成JavaScrip代碼).它的最新版本DWR0.6添加許多特性如:支持Dom Trees的自動配置,支持Spring(JavaScript遠(yuǎn)程調(diào)用spring bean),更好瀏覽器支持,還支持一個可選的commons-logging日記操作.

          以上摘自open-open,它通過反射,將java翻譯成javascript,然后利用回調(diào)機(jī)制,輕松實現(xiàn)了javascript調(diào)用Java代碼。

          其大概開發(fā)過程如下:
          1.編寫業(yè)務(wù)代碼,該代碼是和dwr無關(guān)的。
          2.確認(rèn)業(yè)務(wù)代碼中哪些類、哪些方法是要由javascript直接訪問的。
          3.編寫dwr組件,對步驟2的方法進(jìn)行封裝。
          4.配置dwr組件到dwr.xml文件中,如果有必要,配置convert,進(jìn)行java和javascript類型互轉(zhuǎn)。
          5.通過反射機(jī)制,dwr將步驟4的類轉(zhuǎn)換成javascript代碼,提供給前臺頁面調(diào)用。
          5.編寫網(wǎng)頁,調(diào)用步驟5的javascript中的相關(guān)方法(間接調(diào)用服務(wù)器端的相關(guān)類的方法),執(zhí)行業(yè)務(wù)邏輯,將執(zhí)行結(jié)果利用回調(diào)函數(shù)返回。
          6.在回調(diào)函數(shù)中,得到執(zhí)行結(jié)果后,可以繼續(xù)編寫業(yè)務(wù)邏輯的相關(guān)javascript代碼。

          下面以用戶注冊的例子,來說明其使用。(注意,本次例子只是用于演示,說明DWR的使用,類設(shè)計并不是最優(yōu)的)。

          1.先介紹下相關(guān)的Java類

            User: 用戶類,
            public class User {
          //登陸ID,主鍵唯一
          private String id;
          //姓名
          private String name;
          //口令
          private String password;
          //電子郵件
          private String email;
                  
          //以下包含getXXX和setXXX方法
          .......
            }

            UserDAO:實現(xiàn)User的數(shù)據(jù)庫訪問,這里作為一個演示,編寫測試代碼
            public class UserDAO {
              //存放保存的數(shù)據(jù)
              private static Map dataMap = new HashMap();

              //持久用戶
              public boolean save(User user) {
                if (dataMap.containsKey(user.getId()))
                  return false;
                System.out.println("下面開始保存用戶");
                System.out.println("id:"+user.getId());
                System.out.println("password:"+user.getPassword());
                System.out.println("name:"+user.getName());
                System.out.println("email:"+user.getEmail());
                dataMap.put(user.getId(), user);
                System.out.println("用戶保存結(jié)束");
                return true;
              }

              //查找用戶
              public User find(String id) {
                return (User)dataMap.get(id);
              }
          }

            DWRUserAccess:DWR組件,提供給javascript訪問的。

            public class DWRUserAccess {

                UserDAO userDAO = new UserDAO();

                public boolean save(User user) {
                  return userDAO.save(user);
                }

                public User find(String id) {
                  return userDAO.find(id);
                }
            }
            

            下面說明下程序執(zhí)行的流程

            1.用戶在頁面上輸入相關(guān)注冊信息,id、name、password、email,點擊“提交”按鈕
            2.javascript代碼開始執(zhí)行,根據(jù)用戶填寫相關(guān)信息,通過dwr提供的DWRUserAccess.js里save的方法,調(diào)用服務(wù)器端的DWRUserAccess類save方法,將注冊信息保存。
            3.通過DWRUserAccess.jsp里的find方法,調(diào)用服務(wù)器端DWRUserAccess類里的find方法,執(zhí)行用戶信息查找。

            注意,在以上的執(zhí)行過程中,DWRUserAccess是供DWR調(diào)用的,是DWR組件,因此需要將DWRUserAccess類配置到dwr中。

            接下來講解本次dwr測試環(huán)境的配置。

            1.新建一個webapp,命名為testApp
            2.將dwr.jar拷貝到testApp的WEB-INF的lib目錄下
            3.編譯上面的User,UserDAO,DWRUserAccess類,放到classes目錄下
            4.在web.xml中配置servlet,適配路徑到dwr目錄下,如下所示
              <servlet>
              <servlet-name>dwr-invoker</servlet-name>
              <display-name>DWR Servlet</display-name>
              <description>Direct Web Remoter Servlet</description>
              <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
              <init-param>
                <param-name>debug</param-name>
                <param-value>true</param-value>
              </init-param>
              <init-param>
                <param-name>scriptCompressed</param-name>
                <param-value>false</param-value>
              </init-param>
              <load-on-startup>1</load-on-startup>
            </servlet>

            <servlet-mapping>
              <servlet-name>dwr-invoker</servlet-name>
              <url-pattern>/dwr/*</url-pattern>
            </servlet-mapping>

            以上的配置可以攔截testApp下所有指向dwr的請求,關(guān)于這個攔截器,我們會在后面介紹。

            5.WEB-INF下新建一個dwr.xml文件,內(nèi)容如下:
            < xml version="1.0" encoding="UTF-8" >
          <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

          <dwr>
            <allow>
          <create creator="new" javascript="DWRUserAccess">
                <param name="class" value="test.DWRUserAccess"/>
              </create>
          <convert converter="bean" match="test.User"/>
            </allow>
          </dwr>

            這里我們把DWRUserAccess配置到了dwr中,create元素中,creater="new"表示每調(diào)用一次DWRUserAccess時,需要new一個這樣的類;javascript="DWRUserAccess",表示提供給前臺頁面調(diào)用的javascirpt文件是DWRUserAccess.js。

            convert元素用于數(shù)據(jù)類型轉(zhuǎn)換,即java類和javascript之間相互轉(zhuǎn)換,因為和前臺交換的是User對象,因此需要對此使用bean轉(zhuǎn)換,我們將在后面介紹這個類。

            4.編寫測試的HTML頁面 test.html
             <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE>DWR測試</TITLE>
          <meta http-equiv=Content-Type content="text/html; charset=gb2312">
          <script src="/oblog312/dwr/engine.js"></script>
          <script src="/oblog312/dwr/util.js"></script>
          <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
          </HEAD>
          <BODY>
          <B>用戶注冊</B><br>
          ------------------------------------------------
          <Br>
          <form name="regForm">
          登陸ID:<input type="text" name="id"><br>
          口  令:<input type="password" name="password"><br>
          姓  名:<input type="text" name="name"><br>
          電子郵件:<input type="text" name="email"><br>
          <input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br>
              </form>

          <br>
          <br><B>用戶查詢</B><br>
          ------------------------------------------------
          <Br>
          <form name="queryForm">
          登陸ID:<input type="text" name="id"><br>
          <input type="button" name="submitBtn" value="提交" onclick="OnFind()"><br>
          </form>
          <br>
          </BODY>
          </HTML>
          <SCRIPT LANGUAGE="JavaScript">
          <!--
          function saveFun(data) {
          if (data) {
            alert("注冊成功!");
          } else {
            alert("登陸ID已經(jīng)存在!");
          }
          }

          function OnSave() {
          var userMap = {};
          userMap.id = regForm.id.value;
          userMap.password = regForm.password.value;
          userMap.name = regForm.name.value;
          userMap.email = regForm.email.value;
          DWRUserAccess.save(userMap, saveFun);
          }

          function findFun(data) {
          if (data == null) {
            alert("無法找到用戶:"+queryForm.id.value);
            return;
          }

          alert("找到用戶,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

          }

          function OnFind() {
          DWRUserAccess.find(queryForm.id.value, findFun);
          }
          //-->
          </SCRIPT>


          以下對頁面的javascript進(jìn)行解釋

          <script src="/oblog312/dwr/engine.js"></script>
          <script src="/oblog312/dwr/util.js"></script>
          這兩個是dwr提供的,用戶可以不必關(guān)心,只需要導(dǎo)入即可

          <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
          是我們編寫的DWRUserAccess類,經(jīng)dwr反射后,生成的javascript代碼,它和DWRUserAccess.java是對應(yīng)的,供用戶調(diào)用,實際上我們就是通過這個js文件去調(diào)用服務(wù)器端的DWRUserAccess類的。

          <SCRIPT LANGUAGE="JavaScript">
          <!--
          function saveFun(data) {
          if (data) {
            alert("注冊成功!");
          } else {
            alert("用戶名已經(jīng)存在!");
          }
          }

          function OnSave() {
          var userMap = {};
          userMap.id = regForm.id.value;
          userMap.password = regForm.password.value;
          userMap.name = regForm.name.value;
          userMap.email = regForm.email.value;
          DWRUserAccess.save(userMap, saveFun);
          }

          function findFun(data) {
          if (data == null) {
            alert("無法找到用戶:"+queryForm.id.value);
            return;
          }

          alert("找到用戶,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

          }

          function OnFind() {
          DWRUserAccess.find(queryForm.id.value, findFun);
          }
          //-->
          </SCRIPT>

          這段javascirpt代碼,我們來看下OnSave函數(shù),首先它構(gòu)造一個map,將表單數(shù)據(jù)都設(shè)置到map中,然后調(diào)用DWRUserAccess.save(userMap, saveFun),執(zhí)行save操作。大家可以注意到,服務(wù)器端的DWRUserAccess中的save方法是這樣的:boolean save(User user),其參數(shù)是一個User對象,返回一個boolean值;而客戶端的方法是這樣的:save(userMap,saveFun),第一個參數(shù)userMap是javascirpt中的map對象,在這里相當(dāng)于服務(wù)器端的User對象(在服務(wù)器端執(zhí)行時,會通過convert轉(zhuǎn)換成User對象),前面我們提到dwr是利用回調(diào)函數(shù)來返回執(zhí)行結(jié)果的,第二個參數(shù)saveFun即是一個回調(diào)函數(shù)。在函數(shù)function saveFun(data)中,data是執(zhí)行結(jié)果,這里是一個bool值,非常簡單的,我們通過判斷data是否為真,可以知道用戶名是否重復(fù),用戶是否注冊成功。

          看一下OnFind查找函數(shù),執(zhí)行結(jié)果在回調(diào)函數(shù)findFun(data)中,因為服務(wù)器端返回的是一個User對象,通過convert,將會轉(zhuǎn)換成javascript的一個map對象,
          于是在findFun中,通過data.id、data.name、data.password、data.email我們可以輕松的訪問到這個User對象。


          好了配置完畢,啟動服務(wù)器,在目錄中打入localhost/testApp/test.html。

          1.在“用戶注冊”表單中,id框中輸入admin,password中輸入123456,name中輸入chenbug,email中輸入chenbug@zj.com,點擊提交按鈕,彈出對話框:“注冊成功”,在服務(wù)器后臺可以看到信息如下:

          下面開始保存用戶
          id:admin
          password:123456
          name:chenbug
          email:chenbug@zj.com
          用戶保存結(jié)束

          再次點擊提交按鈕,彈出對話框“登陸ID已經(jīng)存在”。

          2.在“用戶查詢”對話框中,輸入登陸ID為admin,點擊提交按鈕,提示找到用戶,并顯示相關(guān)信息,輸入admin123,點擊提交按鈕,提示無法找到用戶。

          至此,測試結(jié)束。


          后續(xù):
          1。攔截器 uk.ltd.getahead.dwr.DWRServlet
          該類攔截所有指向dwr目錄下的請求,并調(diào)用Processor的handler方法進(jìn)行處理,在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我們可以看到詳細(xì)的處理過程。
          if (pathInfo.length() == 0 ||
                      pathInfo.equals(HtmlConstants.PATH_ROOT) ||
                      pathInfo.equals(req.getContextPath()))
                  {
                      resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX);
                  }
                  else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX))
                  {
                      index.handle(req, resp);
                  }
                  else if (pathInfo.startsWith(HtmlConstants.PATH_TEST))
                  {
                      test.handle(req, resp);
                  }
                  else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE))
                  {
                      iface.handle(req, resp);
                  }
                  else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC))
                  {
                      exec.handle(req, resp);
                  }
                  else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE))
                  {
                      file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
                  }
                  else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL))
                  {
                      file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
                  }
                  else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED))
                  {
                      file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
                  }
                  else
                  {
                      log.warn("Page not found (" + pathInfo + "). In debug/test mode try viewing /[WEB-APP]/dwr/"); //$NON-NLS-1$ //$NON-NLS-2$
                      resp.sendError(HttpServletResponse.SC_NOT_FOUND);
                  }

          通過判斷request請求的servlet路徑,進(jìn)行處理,大家可以自己去參看,這里不詳細(xì)討論。


          2.bean轉(zhuǎn)換器,<convert converter="bean" match="test.User"/>
          將dwr.jar解壓縮,在路徑ukltdgetaheaddwr下可以看到dwr.xml,這里配置了系統(tǒng)默認(rèn)的一些轉(zhuǎn)換器,
          <converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>即是剛才用到User類的轉(zhuǎn)換器,進(jìn)入代碼我們來看看它是如何在javascript和java間進(jìn)行轉(zhuǎn)換的。

          打開BeanConverter代碼,定位到函數(shù)

          public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws ConversionException

          即是將javascript對象轉(zhuǎn)換成java對象的,其中
          paramType即Class類型,在上面的例子中是test.User,
          InboundVariable iv,是傳入的值,通過iv.getValue可以得到傳入的javascript值串
          InboundContext inctx,是入口參數(shù)上下文,用于保存轉(zhuǎn)換的后java對象。

          因為前臺傳入的是一個javascript的map類型,而map肯定是以{開始和以}結(jié)束的,于是在這個函數(shù)一開始進(jìn)行了判斷
          if (!value.startsWith(ConversionConstants.INBOUND_MAP_START))
                  {
                      throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
                  }

                  if (!value.endsWith(ConversionConstants.INBOUND_MAP_END))
                  {
                      throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
                  }

          javascript中,map里各個項是用逗號連接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每個項的鍵值對是用冒號連接的,
          在convertInbound函數(shù)的接下來的處理中,即是通過分析map字串,通過paramType構(gòu)造java實例(即User類),然后通過反射,將這些鍵值對設(shè)置到j(luò)ava實例中,并返回。
          這樣就完成了javascript到j(luò)ava的轉(zhuǎn)換。


          另一個函數(shù)
          public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException

          即是將java對象轉(zhuǎn)換為javascript對象(其實是聲明和賦值語句)。
          Object data ,是待轉(zhuǎn)換的java對象
          String varname,是javascript中的該對象的變量名
          OutboundContext outctx,傳出參數(shù)上下文,用于保存轉(zhuǎn)換后的javascript值

          StringBuffer buffer = new StringBuffer();
                  buffer.append("var "); //$NON-NLS-1$
                  buffer.append(varname);
                  buffer.append("={};"); //$NON-NLS-1$
          這里聲明了map類型的變量。

          即下來來的代碼即是通過反射進(jìn)行變量賦值,如下
            buffer.append(varname);
                              buffer.append('.');
                              buffer.append(name);
                              buffer.append('=');
                              buffer.append(nested.getAssignCode());
                              buffer.append(';');
          大家可以自己去參看更多的代碼。

          3.dwr本身提供了一個測試環(huán)境,大家在配置完后,可以在IE中輸入地址http://localhost/testApp/dwr/index.html,看到配置的各DWR組件,并進(jìn)行相關(guān)測試。
          posted @ 2011-10-13 09:36 甜咖啡 閱讀(294) | 評論 (0)編輯 收藏

          先準(zhǔn)備好軟件:

          Apache官方下載地址:apache_2.0.55-win32-x86-no_ssl.msi更多版本在這里

          php官方下載地址:php-5.0.5-Win32.zip更多鏡像下載地址更多版本下載

          mysql官方下載地址:mysql-4.1.14-win32.zip更多鏡像下載地址更多版本下載

          一、安裝Apache,配置成功一個普通網(wǎng)站服務(wù)器

          運(yùn)行下載好的“apache_2.0.55-win32-x86-no_ssl.msi”,出現(xiàn)如下界面:

           

          出現(xiàn)Apache HTTP Server 2.0.55的安裝向?qū)Ы缑妫c“Next”繼續(xù)

           

          確認(rèn)同意軟件安裝使用許可條例,選擇“I accept the terms in the license agreement”,點“Next”繼續(xù)

           

          將Apache安裝到Windows上的使用須知,請閱讀完畢后,按“Next”繼續(xù)

           

          設(shè)置系統(tǒng)信息,在Network Domain下填入您的域名(比如:goodwaiter.com),在Server Name下填入您的服務(wù)器名稱(比如:www.goodwaiter.com,也就是主機(jī)名加上域名),在Administrator's Email Address下填入系統(tǒng)管理員的聯(lián)系電子郵件地址(比如:yinpeng@xinhuanet.com),上述三條信息僅供參考,其中聯(lián)系電子郵件地址會在當(dāng)系統(tǒng)故障時提供給訪問者,三條信息均可任意填寫,無效的也行。下面有兩個選擇,圖片上選擇的是為系統(tǒng)所有用戶安裝,使用默認(rèn)的80端口,并作為系統(tǒng)服務(wù)自動啟動;另外一個是僅為當(dāng)前用戶安裝,使用端口8080,手動啟動。一般選擇如圖所示。按“Next”繼續(xù)。]

           

          選擇安裝類型,Typical為默認(rèn)安裝,Custom為用戶自定義安裝,我們這里選擇Custom,有更多可選項。按“Next”繼續(xù)

           

          出現(xiàn)選擇安裝選項界面,如圖所示,左鍵點選“Apache HTTP Server 2.0.55”,選擇“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下屬子部分內(nèi)容,全部安裝在本地硬盤上”。點選“Change...”,手動指定安裝目錄。

           

          我這里選擇安裝在“D:\”,各位自行選取了,一般建議不要安裝在操作系統(tǒng)所在盤,免得操作系統(tǒng)壞了之后,還原操作把Apache配置文件也清除了。選“OK”繼續(xù)。

           

          返回剛才的界面,選“Next”繼續(xù)。

           

          確認(rèn)安裝選項無誤,如果您認(rèn)為要再檢查一遍,可以點“Back”一步步返回檢查。點“Install”開始按前面設(shè)定的安裝選項安裝。

           

          正在安裝界面,請耐心等待,直到出現(xiàn)下面的畫面。

           

          安裝向?qū)С晒ν瓿桑@時右下角狀態(tài)欄應(yīng)該出現(xiàn)了下面的這個綠色圖標(biāo),表示Apache服務(wù)已經(jīng)開始運(yùn)行,按“Finish”結(jié)束Apache的軟件安裝

           

          我們來熟悉一下這個圖標(biāo),很方便的,在圖標(biāo)上左鍵單擊,出現(xiàn)如下界面,有“Start(啟動)”、“Stop(停止)”、“Restart(重啟動)”三個選項,可以很方便的對安裝的Apache服務(wù)器進(jìn)行上述操作。

           

          好了現(xiàn)在我們來測試一下按默認(rèn)配置運(yùn)行的網(wǎng)站界面,在IE地址欄打“http://127.0.0.1”,點“轉(zhuǎn)到”,就可以看到如下頁面,表示Apache服務(wù)器已安裝成功。

           

          現(xiàn)在開始配置Apache服務(wù)器,使它更好的替我們服務(wù),事實上,如果不配置,你的安裝目錄下的Apache2\htdocs文件夾就是網(wǎng)站的默認(rèn)根目錄,在里面放入文件就可以了。這里我們還是要配置一下,有什么問題或修改,配置始終是要會的,如圖所示,“開始”、“所有程序”、“Apache HTTP Server 2.0.55”、“Configure Apache Server”、“Edit the Apache httpd conf Configuration file”,點擊打開。

           

          XP的記事本有了些小變化,很實用的一個功能就是可以看到文件內(nèi)容的行、列位置,按下圖所示,點“查看”,勾選“狀態(tài)欄”,界面右下角就多了個標(biāo)記,“Ln 78, Col 10”就表示“行 78,列 10”,這樣可以迅速的在文件中定位,方便解說。當(dāng)然,你也可以通過“編輯”,“查找”輸入關(guān)鍵字來快速定位。每次配置文件的改變,保存后,必須在 Apache服務(wù)器重啟動后生效,可以用前面講的小圖標(biāo)方便的控制服務(wù)器隨時“重啟動”。

           

          現(xiàn)在正式開始配置Apache服務(wù)器,“Ln 228”,或者查找關(guān)鍵字“DocumentRoot”(也就是網(wǎng)站根目錄),找到如下圖所示地方,然后將""內(nèi)的地址改成你的網(wǎng)站根目錄,地址格式請照圖上的寫,主要是一般文件地址的“\”在Apache里要改成“/”。

           

          “Ln 253”,同樣,你也可以通過查找“

           

          “Ln321”,DirectoryIndex(目錄索引,也就是在僅指定目錄的情況下,默認(rèn)顯示的文件名),可以添加很多,系統(tǒng)會根據(jù)從左至右的順序來優(yōu)先顯示,以單個半角空格隔開,比如有些網(wǎng)站的首頁是index.htm,就在光標(biāo)那里加上“index.htm ”文件名是任意的,不一定非得“index.html”,比如“test.php”等,都可以。

           

          這里有一個選擇配置選項,以前可能要配置,現(xiàn)在好像修正過來了,不用配置了,就是強(qiáng)制所有輸出文件的語言編碼,html文件里有語言標(biāo)記(,這個就是設(shè)定文檔語言為gb2312)的也會強(qiáng)制轉(zhuǎn)換。如果打開的網(wǎng)頁出現(xiàn)亂碼,請先檢查網(wǎng)頁內(nèi)有沒有上述 html語言標(biāo)記,如果沒有,添加上去就能正常顯示了。把“# DefaultLanguage nl”前面的“# ”去掉,把“nl”改成你要強(qiáng)制輸出的語言,中文是“zh-cn”,保存,關(guān)閉。

           

          好了,簡單的Apache配置就到此結(jié)束了,現(xiàn)在利用先前的小圖標(biāo)重啟動,所有的配置就生效了,你的網(wǎng)站就成了一個網(wǎng)站服務(wù)器,如果你加載了防火墻,請打開80或8080端口,或者允許Apache程序訪問網(wǎng)絡(luò),否則別人不能訪問。如果你有公網(wǎng)IP(一般ADSL或電話撥號上網(wǎng)的都是),就可以邀請所有能上網(wǎng)的朋友訪問使用http://你的IP地址(IP地址查詢可訪問http://www.goodwaiter.com,查詢內(nèi)容內(nèi)即是)你的網(wǎng)站了;如果你沒有公網(wǎng)IP,也可以把內(nèi)網(wǎng)IP地址告訴局域網(wǎng)內(nèi)的其它用戶,讓他們通過http://你的內(nèi)網(wǎng)IP地址,訪問你的網(wǎng)站。

          二、php的安裝、以module方式,將php與apache結(jié)合使你的網(wǎng)站服務(wù)器支持php服務(wù)器腳本程序

          將下載的php安裝文件php-5.0.5-Win32.zip右鍵解壓縮。

           

          指定解壓縮的位置,我的設(shè)定在“D:\php”

           

          查看解壓縮后的文件夾內(nèi)容,找到“php.ini-dist”文件,將其重命名為“php.ini”,打開編輯,找到下面圖中的地方, Ln385,有一個“register_globals = Off”值,這個值是用來打開全局變量的,比如表單送過來的值,如果這個值設(shè)為“Off”,就只能用“$_POST['變量名']、$_GET['變量名 ']”等來取得送過來的值,如果設(shè)為“On”,就可以直接使用“$變量名”來獲取送過來的值,當(dāng)然,設(shè)為“Off”就比較安全,不會讓人輕易將網(wǎng)頁間傳送的數(shù)據(jù)截取。這個值是否改成“On”就看自己感覺了,是安全重要還是方便重要?

           

          這里還有一個地方要編輯,功能就是使php能夠直接調(diào)用其它模塊,比如訪問mysql,如下圖所示,Ln563,選擇要加載的模塊,去掉前面的 “;”,就表示要加載此模塊了,加載的越多,占用的資源也就多一點,不過也多不到哪去,比如我要用mysql,就要把“;extension= php_mysql.dll”前的“;”去掉。所有的模塊文件都放在php解壓縮目錄的“ext”之下,我這里的截圖是把所有能加載的模塊都加載上去了,前面的“;”沒去掉的,是因為“ext”目錄下默認(rèn)沒有此模塊,加載會提示找不到文件而出錯。這里只是參考,一般不需要加載這么多,需要的加載上就可以了,編輯好后保存,關(guān)閉。

           

          如果上一步加載了其它模塊,就要指明模塊的位置,否則重啟Apache的時候會提示“找不到指定模塊”的錯誤,這里介紹一種最簡單的方法,直接將php安裝路徑、里面的ext路徑指定到windows系統(tǒng)路徑中——在“我的電腦”上右鍵,“屬性”,選擇“高級”標(biāo)簽,點選“環(huán)境變量”,在“系統(tǒng)變量”下找到“Path”變量,選擇,雙擊或點擊“編輯”,將“;D:\php;D:\php\ext”加到原有值的后面,當(dāng)然,其中的“D:\php” 是我的安裝目錄,你要將它改為自己的php安裝目錄,如下圖所示,全部確定。系統(tǒng)路徑添加好后要重啟電腦才能生效,可以現(xiàn)在重啟,也可以在所有軟件安裝或配置好后重啟。

           

          現(xiàn)在開始將php以module方式與Apache相結(jié)合,使php融入Apache,照先前的方法打開Apache的配置文件,Ln 173,找到這里,添加進(jìn)如圖所示選中的兩行,第一行“LoadModule php5_module D:/php/php5apache2.dll”是指以module方式加載php,第二行“PHPIniDir "D:/php"”是指明php的配置文件php.ini的位置,是當(dāng)然,其中的“D:/php”要改成你先前選擇的php解壓縮的目錄。

           

          還是Apache的配置文件,Ln 757,加入“AddType application/x-httpd-php .php”、“AddType application/x-httpd-php .html”兩行,你也可以加入更多,實質(zhì)就是添加可以執(zhí)行php的文件類型,比如你再加上一行“AddType application/x-httpd-php .htm”,則.htm文件也可以執(zhí)行php程序了,你甚至還可以添加上一行“AddType application/x-httpd-php .txt”,讓普通的文本文件格式也能運(yùn)行php程序。

           

          前面所說的目錄默認(rèn)索引文件也可以改一下,因為現(xiàn)在加了php,有些文件就直接存為.php了,我們也可以把“index.php”設(shè)為默認(rèn)索引文件,優(yōu)先順序就自己排了,我的是放在第一位。編輯完成,保存,關(guān)閉。

           

          現(xiàn)在,php的安裝,與Apache的結(jié)合已經(jīng)全部完成,用屏幕右下角的小圖標(biāo)重啟Apache,你的Apache服務(wù)器就支持了php。

          三、mysql的安裝,與php、Apache相結(jié)合

          打開下載的mysql安裝文件mysql-4.1.14-win32.zip,雙擊解壓縮,運(yùn)行“setup.exe”,出現(xiàn)如下界面

           

          mysql安裝向?qū)樱?#8220;Next”繼續(xù)

           

          選擇安裝類型,有“Typical(默認(rèn))”、“Complete(完全)”、“Custom(用戶自定義)”三個選項,我們選擇“Custom”,有更多的選項,也方便熟悉安裝過程

           

          在“Developer Components(開發(fā)者部分)”上左鍵單擊,選擇“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下屬子部分內(nèi)容,全部安裝在本地硬盤上”。在上面的“MySQL Server(mysql服務(wù)器)”、“Client Programs(mysql客戶端程序)”、“Documentation(文檔)”也如此操作,以保證安裝所有文件。點選“Change...”,手動指定安裝目錄。

           

          填上安裝目錄,我的是“D:\mysql”,也建議不要放在與操作系統(tǒng)同一分區(qū),這樣可以防止系統(tǒng)備份還原的時候,數(shù)據(jù)被清空。按“OK”繼續(xù)。

           

          返回剛才的界面,按“Next”繼續(xù)。

           

          確認(rèn)一下先前的設(shè)置,如果有誤,按“Back”返回重做。按“Install”開始安裝。

           

          正在安裝中,請稍候,直到出現(xiàn)下面的界面

           

          這里是詢問你是否要注冊一個mysql.com的賬號,或是使用已有的賬號登陸mysql.com,一般不需要了,點選“Skip Sign-Up”,按“Next”略過此步驟。

           

          現(xiàn)在軟件安裝完成了,出現(xiàn)上面的界面,這里有一個很好的功能,mysql配置向?qū)В挥孟蛞郧耙粯樱约菏謩觼y七八糟的配置my.ini了,將 “Configure the Mysql Server now”前面的勾打上,點“Finish”結(jié)束軟件的安裝并啟動mysql配置向?qū)А?/p>

           

          mysql配置向?qū)咏缑妫?#8220;Next”繼續(xù)。

           

          選擇配置方式,“Detailed Configuration(手動精確配置)”、“Standard Configuration(標(biāo)準(zhǔn)配置)”,我們選擇“Detailed Configuration”,方便熟悉配置過程。

           

          選擇服務(wù)器類型,“Developer Machine(開發(fā)測試類,mysql占用很少資源)”、“Server Machine(服務(wù)器類型,mysql占用較多資源)”、“Dedicated MySQL Server Machine(專門的數(shù)據(jù)庫服務(wù)器,mysql占用所有可用資源)”,大家根據(jù)自己的類型選擇了,一般選“Server Machine”,不會太少,也不會占滿。

           

          選擇mysql數(shù)據(jù)庫的大致用途,“Multifunctional Database(通用多功能型,好)”、“Transactional Database Only(服務(wù)器類型,專注于事務(wù)處理,一般)”、“Non-Transactional Database Only(非事務(wù)處理型,較簡單,主要做一些監(jiān)控、記數(shù)用,對MyISAM數(shù)據(jù)類型的支持僅限于non-transactional),隨自己的用途而選擇了,我這里選擇“Transactional Database Only”,按“Next”繼續(xù)。

           

          對InnoDB Tablespace進(jìn)行配置,就是為InnoDB 數(shù)據(jù)庫文件選擇一個存儲空間,如果修改了,要記住位置,重裝的時候要選擇一樣的地方,否則可能會造成數(shù)據(jù)庫損壞,當(dāng)然,對數(shù)據(jù)庫做個備份就沒問題了,這里不詳述。我這里沒有修改,使用用默認(rèn)位置,直接按“Next”繼續(xù)

           

          選擇您的網(wǎng)站的一般mysql訪問量,同時連接的數(shù)目,“Decision Support(DSS)/OLAP(20個左右)”、“Online Transaction Processing(OLTP)(500個左右)”、“Manual Setting(手動設(shè)置,自己輸一個數(shù))”,我這里選“Online Transaction Processing(OLTP)”,自己的服務(wù)器,應(yīng)該夠用了,按“Next”繼續(xù)

           

          是否啟用TCP/IP連接,設(shè)定端口,如果不啟用,就只能在自己的機(jī)器上訪問mysql數(shù)據(jù)庫了,我這里啟用,把前面的勾打上,Port Number:3306,按“Next”繼續(xù)

           

          這個比較重要,就是對mysql默認(rèn)數(shù)據(jù)庫語言編碼進(jìn)行設(shè)置,第一個是西文編碼,第二個是多字節(jié)的通用utf8編碼,都不是我們通用的編碼,這里選擇第三個,然后在Character Set那里選擇或填入“gbk”,當(dāng)然也可以用“gb2312”,區(qū)別就是gbk的字庫容量大,包括了gb2312的所有漢字,并且加上了繁體字、和其它亂七八糟的字——使用mysql的時候,在執(zhí)行數(shù)據(jù)操作命令之前運(yùn)行一次“SET NAMES GBK;”(運(yùn)行一次就行了,GBK可以替換為其它值,視這里的設(shè)置而定),就可以正常的使用漢字(或其它文字)了,否則不能正常顯示漢字。按 “Next”繼續(xù)。

           

          選擇是否將mysql安裝為windows服務(wù),還可以指定Service Name(服務(wù)標(biāo)識名稱),是否將mysql的bin目錄加入到Windows PATH(加入后,就可以直接使用bin下的文件,而不用指出目錄名,比如連接,“mysql.exe -uusername -ppassword;”就可以了,不用指出mysql.exe的完整地址,很方便),我這里全部打上了勾,Service Name不變。按“Next”繼續(xù)。

           

          這一步詢問是否要修改默認(rèn)root用戶(超級管理)的密碼(默認(rèn)為空),“New root password”如果要修改,就在此填入新密碼(如果是重裝,并且之前已經(jīng)設(shè)置了密碼,在這里更改密碼可能會出錯,請留空,并將“Modify Security Settings”前面的勾去掉,安裝配置完成后另行修改密碼),“Confirm(再輸一遍)”內(nèi)再填一次,防止輸錯。“Enable root access from remote machines(是否允許root用戶在其它的機(jī)器上登陸,如果要安全,就不要勾上,如果要方便,就勾上它)”。最后“Create An Anonymous Account(新建一個匿名用戶,匿名用戶可以連接數(shù)據(jù)庫,不能操作數(shù)據(jù),包括查詢)”,一般就不用勾了,設(shè)置完畢,按“Next”繼續(xù)。

           

          確認(rèn)設(shè)置無誤,如果有誤,按“Back”返回檢查。按“Execute”使設(shè)置生效。

           

          設(shè)置完畢,按“Finish”結(jié)束mysql的安裝與配置——這里有一個比較常見的錯誤,就是不能“Start service”,一般出現(xiàn)在以前有安裝mysql的服務(wù)器上,解決的辦法,先保證以前安裝的mysql服務(wù)器徹底卸載掉了;不行的話,檢查是否按上面一步所說,之前的密碼是否有修改,照上面的操作;如果依然不行,將mysql安裝目錄下的data文件夾備份,然后刪除,在安裝完成后,將安裝生成的 data文件夾刪除,備份的data文件夾移回來,再重啟mysql服務(wù)就可以了,這種情況下,可能需要將數(shù)據(jù)庫檢查一下,然后修復(fù)一次,防止數(shù)據(jù)出錯。

          與Apache及php相結(jié)合,前面已提過,這里再說一下,在php安裝目錄下,找到先前重命名并編輯過的 php.ini,如下圖所示,Ln563,把“;extension=php_mysql.dll”前的“;”去掉,加載mysql模塊。保存,關(guān)閉后,重啟apache就可以了。這里也可以選擇其它要加載的模塊,去掉前面的“;”,就表示要加載此模塊了,加載的越多,占用的資源也就多一點,不過也多不到哪去。所有的模塊文件都放在php解壓縮目錄的“ext”之下,我這里的截圖是把所有能加載的模塊都加載上去了,前面的“;”沒去掉的,是因為“ext” 目錄下默認(rèn)沒有此模塊,加載會提示找不到文件而出錯。這里只是參考,一般不需要加載這么多,需要的加載上就可以了,編輯好后保存,關(guān)閉。

           

          同樣,加載了模塊后,就要指明模塊的位置,否則重啟Apache的時候會提示“找不到指定模塊”的錯誤,這里介紹一種最簡單的方法,直接將 php安裝路徑、里面的ext路徑指定到windows系統(tǒng)路徑中——在“我的電腦”上右鍵,“屬性”,選擇“高級”標(biāo)簽,點選“環(huán)境變量”,在“系統(tǒng)變量”下找到“Path”變量,選擇,雙擊或點擊“編輯”,將“;D:\php;D:\php\ext”加到原有值的后面,當(dāng)然,其中的“D:\php”是我的安裝目錄,你要將它改為自己的php安裝目錄,如下圖所示,全部確定。系統(tǒng)路徑添加好后要重啟電腦才能生效,可以現(xiàn)在重啟,也可以在所有軟件安裝或配置好后重啟。

           
          posted @ 2011-09-27 13:06 甜咖啡 閱讀(199) | 評論 (0)編輯 收藏
          系統(tǒng)主要是通過tomcat運(yùn)行,將tomcat和jre打包后發(fā)送給客戶使用,綠色的方式安裝使用,由于客戶也不搞開發(fā),所以就僅僅是jre和tomcat和應(yīng)用程序
          我使用的jre6,免安裝版版的tomcat6;目錄結(jié)構(gòu)是這樣的

          [我的應(yīng)用名字]
            |-jre6
            |-tomcat6
            |-go_tomcat.bat

          go_tomcat.bat文件內(nèi)容

          @ECHO OFF
          set JRE_HOME=.\jre6
          set PATH=%JRE_HOME%\bin;%PATH%
          set TOMCAT_HOME=.\tomcat6
          cd .\%TOMCAT_HOME%\bin
          rem 啟動tomcat服務(wù)
          .\startup.bat
          posted @ 2011-09-16 18:01 甜咖啡 閱讀(1944) | 評論 (1)編輯 收藏
          僅列出標(biāo)題
          共5頁: 上一頁 1 2 3 4 5 下一頁 

          導(dǎo)航

          <2025年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統(tǒng)計

          常用鏈接

          留言簿(1)

          我參與的團(tuán)隊

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 清镇市| 旬阳县| 长乐市| 正阳县| 贵阳市| 仙桃市| 丹凤县| 将乐县| 丰县| 紫金县| 曲松县| 泰顺县| 襄城县| 平陆县| 探索| 铜川市| 儋州市| 贵州省| 浦县| 光山县| 临安市| 三穗县| 连城县| 阿克苏市| 加查县| 长泰县| 稻城县| 晋江市| 阳山县| 临潭县| 锦州市| 甘孜县| 黔东| 星子县| 德州市| 昭觉县| 普兰县| 雅江县| 哈巴河县| 新丰县| 慈利县|