<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    amp@java

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      99 隨筆 :: 0 文章 :: 228 評(píng)論 :: 0 Trackbacks

    2007年9月18日 #

    當(dāng)年是從CSDN博客遷過(guò)來(lái)的,因?yàn)槟抢锖懿环€(wěn)定,那時(shí)候這里很火的;
    前段時(shí)間發(fā)現(xiàn),Blogjava的登錄頁(yè)面居然沒(méi)有驗(yàn)證碼了,圖片顯示錯(cuò)誤,無(wú)法登錄,預(yù)感這個(gè)地方要涼,只好到處找替代,但沒(méi)找到好用的博客,github是一個(gè)選項(xiàng),但似乎不是很適合做博客。
    現(xiàn)在終于又可以登錄了,不過(guò)首頁(yè)居然只剩一篇文章,我以為數(shù)據(jù)都沒(méi)了,登錄發(fā)現(xiàn)還是有的,不過(guò)太讓人不放心了。
    posted @ 2018-08-18 22:14 amp@java 閱讀(149) | 評(píng)論 (0)編輯 收藏

     昨天下午開(kāi)始,之前用得好好的USB鼠標(biāo),突然不能用了,找到個(gè)PS/2鼠標(biāo),卻發(fā)現(xiàn)主板沒(méi)有鼠標(biāo)的PS/2口,只有鍵盤(pán)的PS/2口,真是奇葩,幸好在用的鍵盤(pán)是PS/2口的,費(fèi)了九牛二虎之力,用鍵盤(pán)操作,Win+R,compmgmt.msc進(jìn)入計(jì)算機(jī)管理,上下箭頭移到設(shè)備管理器,發(fā)現(xiàn)右邊的USB控制器前全是黃色嘆號(hào),嘗試卸載再安裝,卻怎么也裝不上,重新啟動(dòng)發(fā)現(xiàn)鼠標(biāo)在啟動(dòng)Windows前還是亮燈的,但到了顯示W(wǎng)indows徽標(biāo)的時(shí)候燈就滅了,應(yīng)該不是硬件問(wèn)題,而是驅(qū)動(dòng)問(wèn)題。
    為了進(jìn)一步證實(shí)硬件沒(méi)問(wèn)題,找了個(gè)安裝系統(tǒng)的U盤(pán),插進(jìn)去啟動(dòng),能夠正常使用鼠標(biāo),于是目標(biāo)就聚焦在找回驅(qū)動(dòng)上。
    開(kāi)始折騰:
    1、首先是找官方驅(qū)動(dòng)啊,我這電腦是老機(jī),AMD7系列主板,找了半天,這個(gè)主板驅(qū)動(dòng)并沒(méi)有包含USB控制器,因?yàn)閁SB控制器都是Windows自帶的驅(qū)動(dòng),下載了一個(gè)南橋驅(qū)動(dòng),安裝后并沒(méi)有效果;
    2、Windows自帶的驅(qū)動(dòng)原來(lái)都是放在C:\Windows\System32\DriverStore\FileRepository下,USB控制器相關(guān)的驅(qū)動(dòng),就在usbport.inf_amd64_xxxxxxxxxx文件夾里,xxxxxxxxx是一串16進(jìn)制數(shù)字,悲催的是,安裝這個(gè)驅(qū)動(dòng)時(shí)要不提示找不到指定文件,要不說(shuō)第三方INF沒(méi)有簽名;
    3、自己折騰搞不定,找個(gè)軟件吧,第一個(gè)想到的是驅(qū)動(dòng)之家官方的驅(qū)動(dòng)精靈,下載下來(lái)發(fā)現(xiàn)是個(gè)全家桶啊,什么騰訊管家,金山毒霸,瀏覽器首頁(yè)修改一應(yīng)俱全,而且沒(méi)有鼠標(biāo)點(diǎn)擊,用TAB鍵根本移動(dòng)不到取消框,只好默認(rèn)全部安裝了,裝完啟動(dòng),檢測(cè),提示系統(tǒng)自帶驅(qū)動(dòng)缺失,于是回車(chē)修復(fù),但每次修復(fù)完,重新檢測(cè)還是那樣,而且沒(méi)有提示USB控制器驅(qū)動(dòng)安裝有問(wèn)題,有些功能用鍵盤(pán)無(wú)法操作,不知道是不是還有哪里可以操作一下,于是又搜了一下,如何用鍵盤(pán)代替鼠標(biāo),居然真的找到了!
    4、按WIN鍵,輸入設(shè)置,回車(chē),打開(kāi)設(shè)置主頁(yè):

    移到“輕松使用”,進(jìn)去后左邊選擇“鼠標(biāo)”,在右邊啟用“使用數(shù)字小鍵盤(pán)在屏幕上移動(dòng)鼠標(biāo)”(按空格鍵開(kāi)關(guān)),最好把三個(gè)開(kāi)關(guān)都打開(kāi),如果沒(méi)有啟用CTRL鍵加速功能,鼠標(biāo)移動(dòng)非常慢:

    好了,現(xiàn)在可以用小鍵盤(pán)移動(dòng)鼠標(biāo)了;
    5、繼續(xù)回到驅(qū)動(dòng)精靈,再次修復(fù),還是不行啊,這個(gè)東西除了帶來(lái)一堆垃圾,什么作用都沒(méi)有!于是把它帶來(lái)的垃圾以及它自己卸載了。
    6、似乎360也有一個(gè)驅(qū)動(dòng)大師,于是就下載了一個(gè),這個(gè)倒是很純潔,但是功能太弱,完全沒(méi)發(fā)現(xiàn)問(wèn)題;
    7、剛才搜索“安裝驅(qū)動(dòng) 找不到指定的文件”時(shí),發(fā)現(xiàn)一個(gè)論壇提到了這個(gè),是驅(qū)動(dòng)人生的論壇,好像還有解決方案,但要注冊(cè)才能下載,難道驅(qū)動(dòng)人生可以解決?于是就下載了一個(gè)驅(qū)動(dòng)人生,安裝的時(shí)候還是附帶全家桶,不過(guò)現(xiàn)在可以用鍵盤(pán)移動(dòng)鼠標(biāo)取消了,只安裝了驅(qū)動(dòng)人生自己,跟剛才兩個(gè)軟件不同的是,它提示USB外設(shè)驅(qū)動(dòng)沒(méi)有安裝,于是點(diǎn)修復(fù),結(jié)果反反復(fù)復(fù)出現(xiàn)等待光標(biāo),就是無(wú)法完成;
    8、之前又搜索到,驅(qū)動(dòng)安裝的日志在C:\Windows\INF\setupapi.dev.log文件里,于是打開(kāi)這個(gè)文件,發(fā)現(xiàn)Driver package failed signature verification. Error = 0xE000022F,驅(qū)動(dòng)程序簽名有問(wèn)題,所以不能安裝成功;
    9、Windows10有個(gè)高級(jí)啟動(dòng)選項(xiàng)是禁用強(qiáng)制驅(qū)動(dòng)簽名,如何進(jìn)入高級(jí)啟動(dòng)選項(xiàng)呢?以前是按F8,現(xiàn)在不行了,要在設(shè)置里面,更新和安全,恢復(fù),高級(jí)啟動(dòng),立即重啟,然后設(shè)置疑難解答,高級(jí)啟動(dòng),再重啟,就可以進(jìn)入高級(jí)啟動(dòng)菜單,按7進(jìn)入禁止強(qiáng)制驅(qū)動(dòng)簽名模式,重啟后再用驅(qū)動(dòng)人生修復(fù),果然成功了;
    10、打開(kāi)驅(qū)動(dòng)人生下載目錄,DTLFolder\DriversDownLoad,發(fā)現(xiàn)它下載了USB驅(qū)動(dòng)目錄是USB_10.0.10240.16384_WHQL_107049,里面文件如下:

    除了第一個(gè)xml文件是程序自己用的外,其他都是USB驅(qū)動(dòng)用到的文件,點(diǎn)右鍵發(fā)現(xiàn)那幾個(gè)sys文件,除了usbohci.sys和usbuhci.sys外,其他都有數(shù)字簽名,而usbuhci.sys我這里沒(méi)用到,問(wèn)題就出在usbohci.sys上:


    11、難道是驅(qū)動(dòng)人生替換了未簽名的文件?圖謀不軌?為了驗(yàn)證一下,我又下載了一個(gè)Windows10安裝光盤(pán)(版本是當(dāng)前使用的1703版):
    cn_windows_10_multiple_editions_version_1703_updated_march_2017_x64_dvd_10194190.iso
    12、怎么提取安裝光盤(pán)中的內(nèi)置驅(qū)動(dòng)?找了一下,原來(lái)Windows的安裝盤(pán)從VISTA起,不再使用XP以前的I386目錄和Drivers.cab文件存放驅(qū)動(dòng),而是打包在一個(gè)Install.wim鏡像文件中,要找到驅(qū)動(dòng)文件,必須用工具提取,這個(gè)工具就是Imagex.exe,微軟自己做的命令行工具,但是我的電腦上沒(méi)有,于是下載了一個(gè)64位的,放在C盤(pán)根目錄,通過(guò)如下命令即可提取:
    c:\IMAGEX_x64 /mount f:\sources\install.wim 5 i:\1703
    其中F盤(pán)是在iso文件上點(diǎn)右鍵,打開(kāi)方式選“Windows資源管理器”打開(kāi)后虛擬出來(lái)的盤(pán)符,其實(shí)就相當(dāng)于系統(tǒng)自帶的虛擬光驅(qū),I盤(pán)是硬盤(pán),用來(lái)存放掛載的鏡像文件,5是選擇掛載哪一個(gè)版本的Windows(多合一版),如果不知道要掛哪個(gè),把這個(gè)數(shù)字改成100,會(huì)顯示xml文件內(nèi)容,并提示找不到這個(gè)索引號(hào),從xml文件內(nèi)容就能找到各版本的信息,然后再重新掛載正確的即可。這個(gè)掛載其實(shí)是個(gè)解壓縮過(guò)程,時(shí)間很長(zhǎng),提取完之后就跟安裝好了Windows一樣,目錄都列好了。
    今天又發(fā)現(xiàn)另一個(gè)圖形化的工具,Dism++,比這個(gè)操作更簡(jiǎn)單。Dism是PowerShell內(nèi)置的命令,也是與鏡像有關(guān),也能掛載提取,但用了一下似乎提示權(quán)限有問(wèn)題,Dism++是國(guó)內(nèi)開(kāi)源愛(ài)好者自己開(kāi)發(fā)的圖形化工具,與Dism沒(méi)有關(guān)系。
    13、好了,原版的Windows已經(jīng)準(zhǔn)備好,進(jìn)入Windows\System32\DriverStore\FileRepository目錄,搜索usbohci.sys,在usbport.inf_amd64_8e5f608c0111283d目錄下,點(diǎn)右鍵一看,也是沒(méi)簽名的:
    這不是坑爹嗎?你自己帶的東西都沒(méi)簽名,然后又不給用!!!!
    14、有點(diǎn)懷疑是Windows自己更新的時(shí)候修改了一些策略,導(dǎo)致之前可以用的不能用了,為了再次驗(yàn)證,又繼續(xù)下載了兩個(gè)版本的Windows10安裝光盤(pán),分別是早期的1607和最新的1709,找到usbohci.sys,如下所示:
    從左到右依次為1607,1703,1709,均未簽名,基本可以判斷是Windows自己抽風(fēng)了。
    15、昨天晚上搞到12點(diǎn)多,搞定鼠標(biāo)后沒(méi)有重啟測(cè)試,今天早上開(kāi)機(jī),果然發(fā)現(xiàn)鼠標(biāo)又不能用了,因?yàn)槲覜](méi)有選擇禁用強(qiáng)制簽名選項(xiàng)來(lái)啟動(dòng),系統(tǒng)發(fā)現(xiàn)那個(gè)沒(méi)簽名的驅(qū)動(dòng),就把它停了,嘗試卸載,結(jié)果再裝也裝不上,于是只好又設(shè)置高級(jí)啟動(dòng),重新禁止強(qiáng)制簽名,進(jìn)入系統(tǒng),裝上驅(qū)動(dòng),恰好這時(shí)Windows又在后臺(tái)偷偷摸摸地更新,不知道更新了啥,讓我重啟。
    16、重啟之后,奇跡出現(xiàn),剛才明明提示沒(méi)有簽名強(qiáng)制安裝的驅(qū)動(dòng),現(xiàn)在居然正常啟動(dòng)也沒(méi)問(wèn)題了,而且查看驅(qū)動(dòng)詳情的時(shí)候出現(xiàn)了矛盾的一幕:
    外面顯示數(shù)字簽名者:未經(jīng)數(shù)字簽名,里面的sys文件又顯示數(shù)字簽名者是Microsoft Windows,然而進(jìn)入C:\Windows\System32\drivers目錄,找到usbohci.sys,點(diǎn)右鍵,卻發(fā)現(xiàn)并沒(méi)有數(shù)字簽名:
    好吧,你開(kāi)心就好,反正不要再禁我的鼠標(biāo)就行……
    感謝這次蛋疼的折騰之旅,讓我知道了驅(qū)動(dòng)程序來(lái)自哪里,安裝日志在哪里,哪個(gè)軟件坑爹又沒(méi)用,怎么玩安裝盤(pán),怎么用鍵盤(pán)操作鼠標(biāo),怎么進(jìn)入高級(jí)啟動(dòng)界面……
    我為什么要知道這些??????????????為微軟的疏忽買(mǎi)單啊!!!!!
    啥都不說(shuō)了,它又提示我重啟了,不知道又有什么奇跡會(huì)發(fā)生……
    posted @ 2017-11-19 12:43 amp@java 閱讀(1157) | 評(píng)論 (0)編輯 收藏

     每次換手機(jī),把舊手機(jī)的數(shù)據(jù)遷移到新手機(jī)就是個(gè)很麻煩的事情,幸好最近華為的“手機(jī)克隆”APP越來(lái)越強(qiáng)大,居然能夠把微信的聊天記錄包括圖片原封不動(dòng)地遷移到新手機(jī)上,以前用微信自帶的聊天記錄轉(zhuǎn)移功能只能轉(zhuǎn)移文字信息,圖片視頻全部丟失,不知道現(xiàn)在的怎么樣。手機(jī)克隆還能把SD卡的內(nèi)容也轉(zhuǎn)移過(guò)來(lái),基本滿足了需要。
    但是要把手機(jī)上的東西傳到電腦就沒(méi)那么簡(jiǎn)單了,現(xiàn)在已經(jīng)沒(méi)有了以前的大容量存儲(chǔ)模式,只能選擇MTP模式,這種模式其實(shí)不是一個(gè)完整的文件系統(tǒng),有很多限制,所以一些傳統(tǒng)的軟件讀取不到,例如FastCopy是用不了的,用Windows自帶的文件管理器來(lái)復(fù)制,開(kāi)始計(jì)算時(shí)間就要等很久,中間出了個(gè)錯(cuò)就前功盡棄;還有通過(guò)手機(jī)上的APP訪問(wèn)電腦共享的方式,在手機(jī)上復(fù)制也可以,但是同樣會(huì)莫名其妙卡死,F(xiàn)TP同理,折騰了好久,還是覺(jué)得自己動(dòng)手比較好。
    MTP協(xié)議在維基百科里解釋得比較清楚:https://en.wikipedia.org/wiki/Media_Transfer_Protocol ,簡(jiǎn)單點(diǎn)說(shuō)就是:
    1、不是以塊設(shè)備的形式訪問(wèn),跟U盤(pán)不同;
    2、只能單線程訪問(wèn),不能同時(shí)進(jìn)行多個(gè)操作,只能一個(gè)接一個(gè);
    3、控制權(quán)在設(shè)備上,對(duì)外展示的內(nèi)容由設(shè)備決定;
    4、默認(rèn)不能直接對(duì)文件進(jìn)行部分修改,只能復(fù)制過(guò)來(lái)修改完再?gòu)?fù)制回去,但Android對(duì)協(xié)議做了擴(kuò)展,能夠修改部分文件內(nèi)容;
    5、在Linux上有些軟件能夠把它掛載為文件系統(tǒng),這樣其他軟件就能像訪問(wèn)普通文件系統(tǒng)一樣訪問(wèn)了,但是Windows下似乎沒(méi)有。

    不過(guò)有人開(kāi)發(fā)了一個(gè)在Windows下通過(guò)JNI實(shí)現(xiàn)的Java庫(kù)jmtp,項(xiàng)目托管在Google Code,被墻了,但是GitHub有人fork了一個(gè),可以下載下來(lái),我下載的是https://github.com/reindahl/jmtp
    里面包含了C++的代碼和Java的代碼,以及兩個(gè)已經(jīng)編譯好的dll文件,分別用于Win32和Win64,把其中一個(gè)dll文件放在工程目錄下,再把Java源代碼加入工程中即可使用,文檔比較簡(jiǎn)陋,但是看test目錄下的MtpTest.java,基本可以摸到如何使用了,這個(gè)協(xié)議比較簡(jiǎn)單,其實(shí)沒(méi)什么功能,我要的只是把文件復(fù)制到電腦上。
    根據(jù)MtpTest.java,稍微修改一下,做個(gè)遞歸復(fù)制即可把手機(jī)上的所有文件復(fù)制到電腦上:
    package test;

    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.rmi.server.SocketSecurityException;
    import java.util.ArrayList;


    import jmtp.PortableDevice;
    import jmtp.PortableDeviceFolderObject;
    import jmtp.PortableDeviceManager;
    import jmtp.PortableDeviceObject;
    import jmtp.PortableDeviceStorageObject;


    public class TestApp {

       

        
    public static void main(String[] args) {
            
    // TODO Auto-generated method stub
            
            ArrayList
    <PortableDeviceStorageObject> devices = new ArrayList<>();

            PortableDeviceManager manager 
    = new PortableDeviceManager();

            
    for (PortableDevice device : manager) {
                System.out.println(device);
                device.open();
                
                
    // Iterate over deviceObjects
                for (PortableDeviceObject object : device.getRootObjects()) {
                    String storageName
    =object.getName();
                    System.out.println(storageName);

                    
    // If the object is a storage object
                    if (object instanceof PortableDeviceStorageObject) {
                        PortableDeviceStorageObject storage 
    = (PortableDeviceStorageObject) object;
                        System.out.println(storage.getChildObjects().length);
                        
    for (PortableDeviceObject child : storage.getChildObjects()) {
                                copyall(child,
    "E:\\手機(jī)備份\\"+object.getName());
                        }
                    }
                }

                device.close();
                System.out.println(size);
            }

      
      
        }
        
        
    public static void copyall(PortableDeviceObject obj,String path) {

            if(obj instanceof PortableDeviceFolderObject) {
              

                String objName=obj.getName();
                
    if(objName.contains(":")) {
                    objName
    =objName.replace(':''');
                }
                String newPath 
    = path+"\\"+objName;
                System.out.println(
    "創(chuàng)建文件夾:"+newPath);
                
                File file = new File(newPath);
                if(!file.exists()) {
                    file.mkdirs();
                }
                for(PortableDeviceObject subObj:((PortableDeviceFolderObject) obj).getChildObjects()) {             
                    copyall(subObj,newPath);
                }
            }
            
    else {      
                
    if(obj.getName().contains(":"))
                    
    return;
                System.out.println(
    "開(kāi)始復(fù)制文件到:"+path+"\\"+obj.getName());
                File file 
    = new File(path);
                obj.copy(file.toPath());                     
                System.out.println(
    "文件復(fù)制完成!");
            }
        }

    }
    其中發(fā)現(xiàn)有點(diǎn)問(wèn)題:
    1、Android設(shè)備文件名里是可以包含冒號(hào)(:)的,但Windows是不可以的,所以復(fù)制到這些文件的時(shí)候會(huì)有問(wèn)題,于是遇到目錄名這樣就把它改為中文的冒號(hào)(:),但是遇到文件名這樣就不行了,因?yàn)檫@個(gè)庫(kù)的copy函數(shù)只需要指定目標(biāo)目錄,不需要指定目標(biāo)文件名,所以這些文件只能放棄;
    2、Android手機(jī)的MTP協(xié)議是由“媒體存儲(chǔ)”這個(gè)系統(tǒng)APP控制的,有時(shí)候手機(jī)上可以看到的文件,通過(guò)MTP訪問(wèn)卻怎么也看不到,重啟手機(jī)也不行,應(yīng)該就是這個(gè)APP沒(méi)有更新數(shù)據(jù),需要把它的系統(tǒng)數(shù)據(jù)清除掉,等它重建完重新訪問(wèn)就可以看到了,不過(guò)這個(gè)重建時(shí)間非常長(zhǎng),可以查看它數(shù)據(jù)占用的空間,剛清除之后會(huì)發(fā)現(xiàn)它占用的空間會(huì)不斷增長(zhǎng),到了不增長(zhǎng)的時(shí)候就是重建完了,就可以正常訪問(wèn)了;
    3、這個(gè)庫(kù)有時(shí)候還有點(diǎn)bug,有一次發(fā)現(xiàn)它讀取到的文件和文件夾都沒(méi)有了最后一個(gè).后面的部分,所以總是卡住,重新插拔一下手機(jī)數(shù)據(jù)線又沒(méi)問(wèn)題了;
    4、為了避免復(fù)制了半天結(jié)果發(fā)現(xiàn)不完整,又要重來(lái),最好在復(fù)制前先統(tǒng)計(jì)一下文件大小,看看跟手機(jī)上看到的占用存儲(chǔ)空間是不是一致,對(duì)于MTP設(shè)備上的文件,可以通過(guò)getSize函數(shù)得到大小,把上面復(fù)制操作改為大小累加即可,速度比復(fù)制快一些,不過(guò)由于小文件太多,也不會(huì)快很多。

    把手機(jī)里的文件復(fù)制到電腦后,通過(guò)一些簡(jiǎn)單的分析,發(fā)現(xiàn)有很多其實(shí)是垃圾來(lái)的,也可以為手機(jī)空間清理提供參考,因?yàn)樵陔娔X上分析起來(lái)比在手機(jī)上方便一些。例如一些視頻APP的緩存,居然超過(guò)1G,占用了寶貴的內(nèi)部存儲(chǔ)空間,之前一直都沒(méi)發(fā)現(xiàn),通過(guò)電腦里的按文件大小搜索才發(fā)現(xiàn)。
    posted @ 2017-11-17 14:54 amp@java 閱讀(2256) | 評(píng)論 (0)編輯 收藏

    09款老速騰,不支持USB和AUX,要聽(tīng)歌除了CD以外,就是刻錄在CD上的MP3了,以前不知道用什么軟件刻錄了一張碟,能夠完美地顯示中文文件名和ID3信息,前幾天用ImgBurn刻了一張,發(fā)現(xiàn)中文是亂碼,開(kāi)始以為是ID3信息顯示亂碼,于是下載了一個(gè)Mp3Tag,把所有ID3信息都清除,結(jié)果顯示文件名依然亂碼,重新寫(xiě)入ID3信息,發(fā)現(xiàn)ID3可以正常顯示,但文件名還是亂碼。
    于是就把原來(lái)那張可以正常顯示中文的碟拿來(lái)研究一下,發(fā)現(xiàn)它的ID3標(biāo)簽只是ID3v1,而后來(lái)重新寫(xiě)入的ID3是ID3v2.3,兩個(gè)都可以正常顯示中文,說(shuō)明ID3信息是正常的,文件名亂碼不是這個(gè)問(wèn)題。
    但是不知道用什么軟件來(lái)顯示光盤(pán)的文件系統(tǒng),只能一次次摸索。
    幸好有一張CD-RW可以反復(fù)嘗試。
    ImgBurn默認(rèn)是使用ISO9660+UDF,而ISO 9660則使用最老的ISO 9660文件系統(tǒng),也就是1988版本,文件名默認(rèn)是不支持中文的,不知道是不是這個(gè)原因,于是就把文件系統(tǒng)改為ISO 9660+Joliet,如下圖:

    并且把ISO 9660標(biāo)準(zhǔn)改為1999:

    可能是因?yàn)樽址幋a那里改為了ASCII,所以就好了。
    后來(lái)又嘗試只使用UDF文件系統(tǒng),結(jié)果認(rèn)不出碟。



    所以,目前能夠使用中文的環(huán)境其實(shí)就是:
    ImgBurn使用ISO 9660 1999標(biāo)準(zhǔn);
    ID3使用v1或v2.3都可以。

    posted @ 2017-02-10 09:17 amp@java 閱讀(405) | 評(píng)論 (0)編輯 收藏

    最近新部署了一個(gè)信息系統(tǒng),廠家居然沒(méi)有升級(jí)方案,所有數(shù)據(jù)都要重新輸入,包括用戶(hù)、角色等都要重新配置,真是操蛋。要是一個(gè)個(gè)錄入簡(jiǎn)直是日狗了,這些用戶(hù)在其他信息系統(tǒng)早已存在,但是每個(gè)都復(fù)制粘貼提交一遍也不是辦法,于是就想用程序自動(dòng)完成這些操作。步驟如下:
    1、從其他信息系統(tǒng)的數(shù)據(jù)庫(kù)導(dǎo)出用戶(hù)信息,也可以直接從其他信息系統(tǒng)的界面把所有用戶(hù)信息復(fù)制下來(lái)放在一個(gè)文本文件里,反正就是準(zhǔn)備好數(shù)據(jù)源;
    2、在需要錄入用戶(hù)信息的系統(tǒng)中,用人工操作的方式登錄系統(tǒng),并錄入一個(gè)用戶(hù),同時(shí)用Wireshark抓包,查看整個(gè)過(guò)程要提交一些什么樣的表單數(shù)據(jù);
    3、在程序中用httpclient提交同樣的數(shù)據(jù),完成登錄,并從第1步的數(shù)據(jù)源中讀取用戶(hù)信息,然后循環(huán)提交錄入用戶(hù)所需的數(shù)據(jù),完成用戶(hù)的錄入;
    4、新系統(tǒng)沒(méi)有默認(rèn)的用戶(hù)角色,是需要一個(gè)個(gè)修改的,是根據(jù)用戶(hù)的ID來(lái)確定當(dāng)前修改的用戶(hù),并且提交一個(gè)角色I(xiàn)D來(lái)進(jìn)行設(shè)定,因此需要首先獲取用戶(hù)的ID,然后根據(jù)該ID來(lái)提交角色I(xiàn)D,而用戶(hù)ID是通過(guò)用戶(hù)列表頁(yè)面獲取到的,因此還需要通過(guò)正則表達(dá)式來(lái)獲取所有用戶(hù)的ID,然后循環(huán)提交角色I(xiàn)D,完成角色設(shè)定。

    花了不少時(shí)間才搞定,有幾個(gè)地方需要注意:
    1、如果表單數(shù)據(jù)不包含中文,直接把表單的Name和Value加在HttpPost的URL的?后面即可,不需要專(zhuān)門(mén)建立NameValuePair,如下所示:
    HttpPost httppost = new HttpPost("http://1.1.1.1/test/adduser?userid=abc&username=efg");
    httpclient.execute(httppost);

    但是,如果表單數(shù)據(jù)包含中文,例如姓名,用這種方式提交的表單數(shù)據(jù)會(huì)出現(xiàn)亂碼,即使通過(guò)URLEncoder進(jìn)行編碼后再發(fā)也不行,必須建立NameValuePair,再加到HttpPost的Entity里面,如下所示:
    HttpPost httppost = new HttpPost("http://1.1.1.1/test/adduser?userid=abc");
    List
    <NameValuePair> nvps = new ArrayList<NameValuePair>();
    nvps.add(
    new BasicNameValuePair("username","張三"));
    httppost.setEntity(
    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
    httpclient.execute(httppost);

    2、用于網(wǎng)頁(yè)內(nèi)容查找的正則表達(dá)式的使用方式一般為:
    Pattern p = Pattern.compile(".*?abc(whattoget)123.*?");
    Matcher m = p.matcher(line);
    if(m.matches()){
         String whattoget 
    = m.group(1);
    }
    ".*?abc(whattoget)123.*?"就是一個(gè)正則表達(dá)式,如果用于匹配一行的時(shí)候,由于要查找的內(nèi)容是在行中間,所以前后需要加上.*?,表示前后可以是任意字符,也可以什么都沒(méi)有,而表達(dá)式中間的(whattoget)就表示一個(gè)group,編號(hào)為1,編號(hào)為0的group是整個(gè)匹配的字符串,找到之后提取group(1)即可得到想要的內(nèi)容。
    測(cè)試正則表達(dá)式是一項(xiàng)很麻煩的工作,不過(guò)有個(gè)很好的軟件可以完成此工作:RegexBuddy,支持各種語(yǔ)言的正則表達(dá)式的調(diào)試。
    學(xué)習(xí)正則表達(dá)式的寶典是《Mastering Regular Expression》。
    posted @ 2016-01-12 15:54 amp@java 閱讀(3575) | 評(píng)論 (1)編輯 收藏

    今天遇到一個(gè)非常奇怪的問(wèn)題,有臺(tái)裝XP的電腦,插上USB鍵盤(pán)沒(méi)反應(yīng),還以為是鍵盤(pán)壞了,又找來(lái)兩個(gè)不同型號(hào)的鍵盤(pán),依然不行,又以為是USB接口壞了,結(jié)果在電腦啟動(dòng)的時(shí)候又可以按F2進(jìn)入BIOS,這樣就只有一個(gè)原因,Windows的驅(qū)動(dòng)沒(méi)裝上了。
    幸好這電腦還有傳統(tǒng)的PS/2口,而且插上就能識(shí)別,否則連Windows都進(jìn)不去,因?yàn)榘碈trl+Alt+Del沒(méi)反應(yīng)。
    進(jìn)去之后提示安裝USB鍵盤(pán)驅(qū)動(dòng),到最后一步提示安裝失敗,原因是拒絕訪問(wèn)。
    上網(wǎng)搜了一下,安裝驅(qū)動(dòng)拒絕訪問(wèn)的其中一個(gè)原因是注冊(cè)表有個(gè)鍵的權(quán)限設(shè)置有問(wèn)題,改過(guò)來(lái)即可,但是我打開(kāi)注冊(cè)表,連那個(gè)鍵都沒(méi)找到,不是這個(gè)原因。
    不過(guò)從這個(gè)解決方案中也知道了驅(qū)動(dòng)安裝的日志是在Windows目錄下的setupapi.log文件里面,于是打開(kāi)那個(gè)文件,發(fā)現(xiàn)每次安裝都有兩個(gè)拒絕訪問(wèn)的錯(cuò)誤,但并沒(méi)有說(shuō)是注冊(cè)表拒絕訪問(wèn),在拒絕訪問(wèn)之前,還提到一個(gè)叫MlCoInst.dll的文件沒(méi)有簽名。
    上網(wǎng)搜MlCoInst.dll,沒(méi)有找到任何結(jié)果,在System32目錄下找到它,看屬性,果然沒(méi)有簽名,是個(gè)三無(wú)文件,不知道為什么每次安裝驅(qū)動(dòng)都要調(diào)用它。
    日志里面還提到了“共同安裝程序”,似乎和CoInst有點(diǎn)關(guān)聯(lián),于是又查了一下,原來(lái)安裝驅(qū)動(dòng)的時(shí)候可以通過(guò)調(diào)用“共同安裝程序”來(lái)實(shí)現(xiàn)某些目的,例如修改驅(qū)動(dòng)程序的簽名狀態(tài),欺騙操作系統(tǒng),這樣就可以只安裝一次驅(qū)動(dòng)即可,不用每次插入都安裝一次。
    于是嘗試把MlCoInst.dll刪除,提示刪除失敗。
    在注冊(cè)表里面搜索MlCoInst.dll,把所有找到的鍵值都刪除,再次插拔鍵盤(pán),順利安裝完畢,刪除MlCoInst.dll,也成功了,果然是它的問(wèn)題。

    這個(gè)應(yīng)該是某個(gè)USB設(shè)備的驅(qū)動(dòng)引進(jìn)來(lái)的,而且修改了usb.inf,每次安裝任何USB設(shè)備都要調(diào)用它,但它可能與Windows的簽名機(jī)制有沖突,所以導(dǎo)致安裝失敗,真是坑爹!
    posted @ 2015-04-02 17:04 amp@java 閱讀(3605) | 評(píng)論 (0)編輯 收藏

    做GUI程序的時(shí)候,通常有個(gè)后臺(tái)工作線程在努力工作,但是中間又需要一些暫停,而關(guān)閉程序的時(shí)候,必須立即結(jié)束那個(gè)線程,退出程序,也有的時(shí)候需要停止后臺(tái)線程,但不關(guān)閉程序。例如,做一個(gè)目錄監(jiān)控程序,發(fā)現(xiàn)目錄中有文件的時(shí)候,執(zhí)行一定的操作,執(zhí)行完之后沒(méi)有文件了,就要暫停一下,過(guò)幾秒或幾分鐘再次檢測(cè),這時(shí)候就要對(duì)線程進(jìn)行暫停操作,如果在暫停的時(shí)候,用戶(hù)要關(guān)閉程序,就必須馬上停止線程,如果用戶(hù)需要暫停檢測(cè),按下某個(gè)按鈕后,需要讓線程馬上停止,但再次按下某個(gè)按鈕,線程又必須馬上開(kāi)始。

    以前我都是通過(guò)檢測(cè)停止標(biāo)記和用Thread.sleep(time)來(lái)完成的,后臺(tái)線程的每次循環(huán)都要檢查停止標(biāo)記,如果發(fā)現(xiàn)停止標(biāo)記已設(shè)定,就不再循環(huán),退出線程,在線程內(nèi)部,如果需要暫停,就執(zhí)行Thread.sleep(time)。通過(guò)把線程的setDaemon(true)方法,還可以讓線程作為后臺(tái)線程,當(dāng)圖形界面關(guān)閉后,線程也自動(dòng)退出。

    但是,這種方式有個(gè)問(wèn)題,如果我需要在圖形界面上點(diǎn)擊按鈕來(lái)停止線程,但并不退出程序,而點(diǎn)擊按鈕的時(shí)候線程正處于sleep狀態(tài),就對(duì)它沒(méi)有任何辦法,只能讓它醒過(guò)來(lái)再操作,如果sleep的時(shí)間比較長(zhǎng),例如1分鐘,那么點(diǎn)擊按鈕之后,用戶(hù)最多要等1分鐘才能把線程停下來(lái)。當(dāng)然,Thread對(duì)象有個(gè)interrupt方法,但是已經(jīng)被標(biāo)記為過(guò)期,一般不建議使用了。感謝評(píng)論中watchzerg的提醒,Thread的interrupt()并沒(méi)有標(biāo)記為過(guò)期,可以按照他的說(shuō)法來(lái)操作,更為簡(jiǎn)單。

    怎么讓線程能暫停,又能隨時(shí)叫醒呢?原來(lái)Java里最原始的對(duì)象Object就自帶此功能。

    每個(gè)Object都有wait(time)和notify()方法,前者就是讓擁有該Obejct的線程處于暫停狀態(tài),后者則讓線程馬上喚醒,通過(guò)這兩個(gè)方法,就能夠滿足上述的所有要求。

    首先,建立一個(gè)同步對(duì)象:
    Object syncObj = new Object();

    然后在線程中需要暫停的地方,調(diào)用該對(duì)象的wait(time)方法:
    synchronized (syncObj) {
           syncObj.wait(60*1000);
    }

    在圖形界面的按鈕監(jiān)聽(tīng)事件中,對(duì)該對(duì)象執(zhí)行notify()方法:
            button_1.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {

                    thread.setStop(true);
                    synchronized (syncObj) {
                            syncObj.notify();
                     }
                    //為了等待線程退出,還可以加上以下語(yǔ)句:
                    thread.join();

                }
            });

    posted @ 2015-03-10 16:52 amp@java 閱讀(7692) | 評(píng)論 (2)編輯 收藏

    Eclipse有個(gè)功能就是把整個(gè)項(xiàng)目打包成一個(gè)可執(zhí)行的Jar文件,里面包含了所有項(xiàng)目引用了的庫(kù),如果電腦上安裝了JRE,直接雙擊就可以啟動(dòng),看起來(lái)很方便,如下圖所示:

    可以選擇把所有類(lèi)庫(kù)打包進(jìn)去,也就是Jar里面還包含一堆Jar:

    還可以生成ant腳本:


    生成的jar文件,可以直接通過(guò)java -jar xx.jar啟動(dòng),簡(jiǎn)單快捷。


    然而,這樣導(dǎo)出來(lái)的可執(zhí)行jar,啟動(dòng)速度卻非常慢,這跟包的大小有關(guān)。有個(gè)項(xiàng)目導(dǎo)出來(lái)的包有40MB,結(jié)果啟動(dòng)需要近一分鐘,在性能差的電腦上,甚至要幾分鐘,就是你執(zhí)行完命令后,沒(méi)有任何界面顯示,但是查看任務(wù)管理器發(fā)現(xiàn)java進(jìn)程的CPU占用率在浮動(dòng),說(shuō)明正在努力啟動(dòng),過(guò)了一段時(shí)間之后界面突然顯示出來(lái),簡(jiǎn)直讓人崩潰。可是在Eclipse里面運(yùn)行,卻是一點(diǎn)就開(kāi)。

    我開(kāi)始嘗試縮小導(dǎo)出的包。但是Eclipse的導(dǎo)出對(duì)話框并沒(méi)有提供需要打包哪些庫(kù)的選項(xiàng),都是默認(rèn)把所有庫(kù)都打包進(jìn)去,但是它可以生成ant腳本,可以通過(guò)編輯ant腳本的方式來(lái)減少不必要的庫(kù)。經(jīng)過(guò)多次嘗試,終于把40MB的包縮成了17MB,啟動(dòng)速度快了一些,但是依然需要半分鐘以上。

    后來(lái)覺(jué)得,能不能不打包直接運(yùn)行呢?于是把導(dǎo)出來(lái)的包用壓縮軟件解壓,再把里面包含的jar包繼續(xù)解壓,最后得到一堆沒(méi)有壓縮的class文件,再通過(guò)指定classpath的方式,直接運(yùn)行程序入口class,發(fā)現(xiàn)啟動(dòng)速度和在Eclipse里面一樣,一點(diǎn)就開(kāi)。

    打包的好處是部署簡(jiǎn)單,只需要一個(gè)文件,但帶來(lái)的缺點(diǎn)實(shí)在不能忍,打散的方式部署起來(lái)稍微難一點(diǎn),但是啟動(dòng)速度夠快,對(duì)普通用戶(hù)來(lái)說(shuō),這個(gè)才是最重要的。

    當(dāng)然,還有一種方式是像Eclipse那樣,啟動(dòng)時(shí)顯示一個(gè)圖片,底下一個(gè)進(jìn)度條顯示啟動(dòng)進(jìn)度,不過(guò)這樣也加大了工作量,而且每次都要等那進(jìn)度條,實(shí)際上也很煩。
    posted @ 2015-03-10 15:07 amp@java 閱讀(5143) | 評(píng)論 (0)編輯 收藏

         摘要: JMF太老了,各種問(wèn)題得不到解決,Oracle也沒(méi)再升級(jí)過(guò),如果能找到新東西,最好能把它扔掉。最近OpenCV比較火,還有人用Java封裝了OpenCV,成立了JavaCV項(xiàng)目,通過(guò)改造VideoInput這個(gè)基于C語(yǔ)言的項(xiàng)目,能夠用Java來(lái)調(diào)用攝像頭,JMF可以扔掉了。如果想測(cè)試,非常簡(jiǎn)單,把那些編譯好的jar文件放入Build Path即可,如果是在Windows X86環(huán)境下,則只需要把帶...  閱讀全文
    posted @ 2015-02-15 11:41 amp@java 閱讀(10432) | 評(píng)論 (7)編輯 收藏

    其實(shí)我覺(jué)得用java結(jié)合SQL來(lái)做同樣的事情更簡(jiǎn)單,但是EXCEL的好處是不用編程,雖然里面有好多陷阱,但是掌握之后能夠熟練運(yùn)用還是比每次都編個(gè)程序更簡(jiǎn)單。VLOOKUP函數(shù)的使用比較復(fù)雜,搞了好久都不明白,終于找到了下面這篇文章,解決了很多問(wèn)題。

    以下是轉(zhuǎn)載文章,原來(lái)的出處不知道是哪里,應(yīng)該是來(lái)自

    http://www.excelpx.com
    但具體的地址不詳。



    VLOOKUP函數(shù)是Excel中幾個(gè)最重函數(shù)之一,為了方便大家學(xué)習(xí),蘭色幻想特針對(duì)VLOOKUP函數(shù)的使用和擴(kuò)展應(yīng)用,進(jìn)行一次全面綜合的說(shuō)明。本文為入門(mén)部分

         一、入門(mén)級(jí)

          VLOOKUP是一個(gè)查找函數(shù),給定一個(gè)查找的目標(biāo),它就能從指定的查找區(qū)域中查找返回想要查找到的值。它的基本語(yǔ)法為:

          VLOOKUP(查找目標(biāo)查找范圍返回值的列數(shù)精確OR模糊查找)

    下面以一個(gè)實(shí)例來(lái)介紹一下這四個(gè)參數(shù)的使用

         例1:如下圖所示,要求根據(jù)表二中的姓名,查找姓名所對(duì)應(yīng)的年齡。  

       公式:B13 =VLOOKUP(A13,$B$2:$D$8,3,0)  

       參數(shù)說(shuō)明:

           1 查找目標(biāo):就是你指定的查找的內(nèi)容或單元格引用。本例中表二A列的姓名就是查找目標(biāo)。我們要根據(jù)表二的“姓名”在表一中A列進(jìn)行查找。

            公式:B13 =VLOOKUP(A13,$B$2:$D$8,3,0)   

           2 查找范圍(VLOOKUP(A13,$B$2:$D$8,3,0) : 指定了查找目標(biāo),如果沒(méi)有說(shuō)從哪里查找,EXCEL肯定會(huì)很為難。所以下一步我們就要指定從哪個(gè)范圍中進(jìn)行查找。VLOOKUP的這第二個(gè)參數(shù)可以從一個(gè) 單元格區(qū)域中查找,也可以從一個(gè)常量數(shù)組或內(nèi)存數(shù)組中查找。本例中要從表一中進(jìn)行查找,那么范圍我們要怎么指定呢?這里也是極易出錯(cuò)的地方。大家一定要注 意,給定的第二個(gè)參數(shù)查找范圍要符合以下條件才不會(huì)出錯(cuò):

            A 查找目標(biāo)一定要在該區(qū)域的第一列。本例中查找表二的姓名,那么姓名所對(duì)應(yīng)的表一的姓名列,那么表一的姓名列(列)一定要是查找區(qū)域的第一列。象本例中,給定的區(qū)域要從第二列開(kāi)始,即$B$2:$D$8,而不能是$A$2:$D$8。因?yàn)椴檎业?#8220;姓名”不在$A$2:$D$8區(qū)域的第一列。

            B 該區(qū)域中一定要包含要返回值所在的列,本例中要返回的值是年齡。年齡列(表一的D列)一定要包括在這個(gè)范圍內(nèi),即:$B$2:$D$8,如果寫(xiě)成$B$2:$C$8就是錯(cuò)的。

           3 返回值的列數(shù)(B13 =VLOOKUP(A13,$B$2:$D$8,3,0))。這是VLOOKUP第3個(gè)參數(shù)。它是一個(gè)整數(shù)值。它怎么得來(lái)的呢。它是“返回值”在第二個(gè)參數(shù)給定的區(qū)域中的列數(shù)。本例中我們要返回的是“年齡”,它是第二個(gè)參數(shù)查找范圍$B$2:$D$8的第3列。這里一定要注意,列數(shù)不是在工作表中的列數(shù)(不是第4列),而是在查找范圍區(qū)域的第幾列。如果本例中要是查找姓名所對(duì)應(yīng)的性別,第3個(gè)參數(shù)的值應(yīng)該設(shè)置為多少呢。答案是2。因?yàn)樾詣e在$B$2:$D$8的第2列中。

           4 精確OR模糊查找(VLOOKUP(A13,$B$2:$D$8,3,0)  ),最后一個(gè)參數(shù)是決定函數(shù)精確和模糊查找的關(guān)鍵。精確即完全一樣,模糊即包含的意思。第4個(gè)參數(shù)如果指定值是0或FALSE就表示精確查找,而值為1 或TRUE時(shí)則表示模糊。這里蘭色提醒大家切記切記,在使用VLOOKUP時(shí)千萬(wàn)不要把這個(gè)參數(shù)給漏掉了,如果缺少這個(gè)參數(shù)默為值為模糊查找,我們就無(wú)法精確查找到結(jié)果了。  

          好了,關(guān)于VLOOKUP函數(shù)的入門(mén)級(jí)應(yīng)用就說(shuō)到這里,VLOOKUP函數(shù)可不只是這么簡(jiǎn)單的查找,我們講的還只是1/10的用法。其他的沒(méi)法在一篇文章中說(shuō)明。敬請(qǐng)期待“VLOOKUP的使用方法-進(jìn)階篇”吧。

     

    上一講咱們學(xué)習(xí)了VLOOKUP的基本用法和示例,本講將介紹VLOOKUP在使用中的一些小技巧。

    Excel函數(shù)速成教程全系列(包括VLOOKUP函數(shù),IF函數(shù),offset函數(shù),sumif函數(shù)等66個(gè)函數(shù))預(yù)計(jì)6月初全部錄制完成,現(xiàn)已在淘寶開(kāi)始預(yù)訂(8折優(yōu)惠),地址:http://item.taobao.com/item.htm?id=17500884347

    一、VLOOKUP多行查找時(shí)復(fù)制公式的問(wèn)題

        VLOOKUP函數(shù)的第三個(gè)參數(shù)是查找返回值所在的列數(shù),如果我們需要查找返回多列時(shí),這個(gè)列數(shù)值需要一個(gè)個(gè)的更改,比如返回第2列的,參數(shù)設(shè)置為2,如 果需要返回第3列的,就需要把值改為3。。。如果有十幾列會(huì)很麻煩的。那么能不能讓第3個(gè)參數(shù)自動(dòng)變呢?向后復(fù)制時(shí)自動(dòng)變?yōu)?,3,4,5。。。   

        在EXCEL中有一個(gè)函數(shù)COLUMN,它可以返回指定單元格的列數(shù),比如

             =COLUMNS(A1) 返回值1

             =COLUMNS(B1) 返回值2

       而單元格引用復(fù)制時(shí)會(huì)自動(dòng)發(fā)生變化,即A1隨公式向右復(fù)制時(shí)會(huì)變成B1,C1,D1。。這樣我們用COLUMN函數(shù)就可以轉(zhuǎn)換成數(shù)字1,2,3,4。。。 

        例:下例中需要同時(shí)查找性別,年齡,身高,體重。

       

         公式:=VLOOKUP($A13,$B$2:$F$8,COLUMN(B1),0)

      公式說(shuō)明:這里就是使用COLUMN(B1)轉(zhuǎn)化成可以自動(dòng)遞增的數(shù)字。

    二、VLOOKUP查找出現(xiàn)錯(cuò)誤值的問(wèn)題。

        1、如何避免出現(xiàn)錯(cuò)誤值。

         EXCEL2003 在VLOOKUP查找不到,就#N/A的錯(cuò)誤值,我們可以利用錯(cuò)誤處理函數(shù)把錯(cuò)誤值轉(zhuǎn)換成0或空值。

          即:=IF(ISERROR(VLOOKUP(參數(shù)略)),"",VLOOKUP(參數(shù)略)

         EXCEL2007,EXCEL2010中提供了一個(gè)新函數(shù)IFERROR,處理起來(lái)比EXCEL2003簡(jiǎn)單多了。

         IFERROR(VLOOKUP(),"") 

        2、VLOOKUP函數(shù)查找時(shí)出現(xiàn)錯(cuò)誤值的幾個(gè)原因

          A、實(shí)在是沒(méi)有所要查找到的值

          B、查找的字符串或被查找的字符中含有空格或看不見(jiàn)的空字符,驗(yàn)證方法是用=號(hào)對(duì)比一下,如果結(jié)果是FALSE,就表示兩個(gè)單元格看上去相同,其實(shí)結(jié)果不同。

          C、參數(shù)設(shè)置錯(cuò)誤。VLOOKUP的最后一個(gè)參數(shù)沒(méi)有設(shè)置成1或者是沒(méi)有設(shè)置掉。第二個(gè)參數(shù)數(shù)據(jù)源區(qū)域,查找的值不是區(qū)域的第一列,或者需要反回的字段不在區(qū)域里,參數(shù)設(shè)置在入門(mén)講里已注明,請(qǐng)參閱。

         D、數(shù)值格式不同,如果查找值是文本,被查找的是數(shù)字類(lèi)型,就會(huì)查找不到。解決方法是把查找的轉(zhuǎn)換成文本或數(shù)值,轉(zhuǎn)換方法如下:

         文本轉(zhuǎn)換成數(shù)值:*1或--或/1

         數(shù)值轉(zhuǎn)抱成文本:&""  

         VLOOKUP函數(shù)的初級(jí)篇就說(shuō)到這里了,咱們下一講將介紹VLOOKUP的模糊查找有、反向查找等。

     

     在學(xué)習(xí)了VLOOKUP的入門(mén)和初級(jí)篇后,本文將帶將大家學(xué)習(xí)VLOOKUP的進(jìn)階篇:VLOOKUP的模糊查找。

        一、字符的模糊查找    

            在A列我們知道如何查找型號(hào)為“AAA”的產(chǎn)品所對(duì)應(yīng)的B列價(jià)格,即:

        =VLOOKUP(C1,A:B,2,0)

           如果我們需要查找包含“AAA”的產(chǎn)品名稱(chēng)怎么表示呢?如下圖表中所示。

         公式=VLOOKUP("*"&A10&"*",A2:B6,2,0)  

        公式說(shuō)明:VLOOKUP的第一個(gè)參數(shù)允許使用通配符“*”來(lái)表示包含的意思,把*放在字符的兩邊,即"*" & 字符 & "*"。

       二、數(shù)字的區(qū)間查找

          數(shù)字的區(qū)間查找即給定多個(gè)區(qū)間,指定一個(gè)數(shù)就可以查找出它在哪個(gè)區(qū)間并返回這個(gè)區(qū)間所對(duì)應(yīng)的值。

        在VLOOKUP入門(mén)中我們提示VLOOKUP的第4個(gè)參數(shù),如果為0或FALSE是精確查找,如果是1或TRUE或省略則為模糊查找,那么實(shí)現(xiàn)區(qū)間查找正是第4個(gè)參數(shù)的模糊查找應(yīng)用。

        首先我們需要了解一下VLOOKUP函數(shù)模糊查找的兩個(gè)重要規(guī)則:

        1、引用的數(shù)字區(qū)域一定要從小到大排序。雜亂的數(shù)字是無(wú)法準(zhǔn)確查找到的。如下面A列符合模糊查找的前題,B列則不符合 

        

        2、模糊查找的原理是給一定個(gè)數(shù),它會(huì)找到和它最接近,但比它小的那個(gè)數(shù)。詳見(jiàn)下圖說(shuō)明。

        

       最后看一個(gè)實(shí)例: 

        例:如下圖所示,要求根據(jù)上面的提成比率表,在提成表計(jì)算表中計(jì)算每個(gè)銷(xiāo)售額的提成比率和提成額。

        

       公式:=VLOOKUP(A11,$A$3:$B$7,2)

       公式說(shuō)明:

        1、上述公式省略了VLOOKUP最后一個(gè)參數(shù),相當(dāng)于把第四個(gè)參數(shù)設(shè)置成1或TRUE。這表示VLOOKUP要進(jìn)行數(shù)字的區(qū)間查找。

        2、圖中公式中在查找5000時(shí)返回比率表0所對(duì)應(yīng)的比率1%,原因是0和10000與5000最接近,但VLOOKUP只選比查找值小的那一個(gè),所以公式會(huì)返回0所對(duì)應(yīng)的比率1%。

     

     前言:前面我們分別學(xué)習(xí)了VLOOKUP函數(shù)的入門(mén)、初級(jí)和進(jìn)階篇。今天我們學(xué)習(xí)VLOOKUP函數(shù)的高級(jí)應(yīng)用部分-VLOOKUP函數(shù)的數(shù)組應(yīng)用。(本文由蘭色幻想原創(chuàng),轉(zhuǎn)載請(qǐng)注明轉(zhuǎn)自excel精英培訓(xùn)

     一、VLOOKUP的反向查找。

        一般情況下,VLOOKUP函數(shù)只能從左向右查找。但如果需要從右向右查找,則需要把區(qū)域進(jìn)行“乾坤大挪移”,把列的位置用數(shù)組互換一下。

        例1:要求在如下圖所示表中的姓名反查工號(hào)。

         

        公式:=VLOOKUP(A9,IF({1,0},B2:B5,A2:A5),2,0)

        公式剖析:

            1、這里其實(shí)不是VLOOKUP可以實(shí)現(xiàn)從右至右的查找,而是利用IF函數(shù)的數(shù)組效應(yīng)把兩列換位重新組合后,再按正常的從左至右查找。

            2、IF({1,0},B2:B5,A2:A5)這是本公式中最重要的組成部分。在EXCEL函數(shù)中使用數(shù)組時(shí)(前提時(shí)該函數(shù)的參數(shù)支持?jǐn)?shù)組),返回的結(jié) 果也會(huì)是一個(gè)數(shù)組。這里1和0不是實(shí)際意義上的數(shù)字,而是1相關(guān)于TRUE,0相當(dāng)于FALSE,當(dāng)為1時(shí),它會(huì)返回IF的第二個(gè)參數(shù)(B列),為0時(shí)返 回第二個(gè)參數(shù)(A列)。根據(jù)數(shù)組運(yùn)算返回?cái)?shù)組,所以使用IF后的結(jié)果返回一個(gè)數(shù)組(非單元格區(qū)域):{"張一","A001";"趙 三","A002";"楊五","A003";"孫二","A004"}

     二、VLOOKUP函數(shù)的多條件查找。

          VLOOKUP函數(shù)需要借用數(shù)組才能實(shí)現(xiàn)多條件查找。

         例2:要求根據(jù)部門(mén)和姓名查找C列的加班時(shí)間。

         分析:我們可以延用例1的思路,我們的努力方向不是讓VLOOKUP本身實(shí)現(xiàn)多條件查找,而是想辦法重構(gòu)一個(gè)數(shù)組。多個(gè)條件我們可以用&連接在一起,同樣兩列我們也可以連接成一列數(shù)據(jù),然后用IF函數(shù)進(jìn)行組合。

        公式:{=VLOOKUP(A9&B9,IF({1,0},A2:A5&B2:B5,C2:C5),2,0)}

        公式剖析:

           1、A9&B9 把兩個(gè)條件連接在一起。把他們做為一個(gè)整體進(jìn)行查找。

           2、A2:A5&B2:B5,和條件連接相對(duì)應(yīng),把部分和姓名列也連接在一起,作為一個(gè)待查找的整體。

           3、IF({1,0},A2:A5&B2:B5,C2:C5) 用IF({1,0}把連接后的兩列與C列數(shù)據(jù)合并成一個(gè)兩列的內(nèi)存數(shù)組。按F9后可以查看的結(jié)果為:

           {"銷(xiāo)售張一",1;"銷(xiāo)售趙三",5;"人事楊五",3;"銷(xiāo)售趙三",6}

           4、完成了數(shù)組的重構(gòu)后,接下來(lái)就是VLOOKUP的基本查找功能了,另外公式中含有多個(gè)數(shù)據(jù)與多個(gè)數(shù)據(jù)運(yùn)算(A2:A5&B2:B5),,所以必須以數(shù)組形式輸入,即按ctrl+shift后按ENTER結(jié)束輸入。

         三、VLOOKUP函數(shù)的批量查找。

         VLOOKUP一般情況下只能查找一個(gè),那么多項(xiàng)該怎么查找呢?

         例3 要求把如圖表中所有張一的消費(fèi)金額全列出來(lái)

         分析:經(jīng)過(guò)前面的學(xué)習(xí),我們也有這樣一個(gè)思路,我們?cè)趯?shí)現(xiàn)復(fù)雜的查找時(shí),努力的方向是怎么重構(gòu)一個(gè)查找內(nèi)容和查找的區(qū)域。要想實(shí)現(xiàn)多項(xiàng)查找,我們可以對(duì)查找的內(nèi)容進(jìn)行編號(hào),第一個(gè)出現(xiàn)的是后面連接1,第二個(gè)出現(xiàn)的連接2。。。

         公式:{=VLOOKUP(B$9&ROW(A1),IF({1,0},$B$2:$B$6&COUNTIF(INDIRECT("b2:b"&ROW($2:$6)),B$9),$C$2:$C$6),2,)}

         公式剖析:

            1、B$9&ROW(A1) 連接序號(hào),公式向下復(fù)制時(shí)會(huì)變成B$9連接1,2,3

            2、給所有的張一進(jìn)行編號(hào)。要想生成編號(hào),就需要生成一個(gè)不斷擴(kuò)充的區(qū)域(INDIRECT("b2:b"&ROW($2:$6)),然后在這個(gè)逐行擴(kuò)充的區(qū)域內(nèi)統(tǒng)計(jì)“張一”的個(gè)數(shù),在連接上$B$2:$B$6后就可以對(duì)所有的張一進(jìn)行編號(hào)了。

           3、IF({1,0}把編號(hào)后的B列和C組重構(gòu)成一個(gè)兩列數(shù)組

         通過(guò)以上的講解,我們需要知道,VLOOKUP函數(shù)的基本用法是固定的,要實(shí)現(xiàn)高級(jí)查找,就需要借助其他函數(shù)來(lái)重構(gòu)查找內(nèi)容和查找數(shù)組。

         至此VLOOKUP函數(shù)從入門(mén)到高級(jí)的四篇VLOOKUP函數(shù)使用教程全部結(jié)束了,VLOOKUP函數(shù)在數(shù)組運(yùn)算中還有著其他應(yīng)用,但只是配角了,所以本系列不再介紹。由于筆者水平有限,不免有錯(cuò)漏之處,請(qǐng)大家多多指點(diǎn)。

    posted @ 2014-12-16 09:10 amp@java 閱讀(520) | 評(píng)論 (0)編輯 收藏

    JMF(Java Media Framework)是Java平臺(tái)使用攝像頭、麥克風(fēng)等媒體設(shè)備的應(yīng)用程序框架,但到了2.1.1e就不再更新,在Windows 7 X64上還能正常運(yùn)行,只是安裝的界面讓你感覺(jué)回到了Windows98的時(shí)代。


    不過(guò)年代久遠(yuǎn)的東西,雖然還能用,但可能會(huì)遇到一些奇怪的問(wèn)題,折騰了兩個(gè)月,發(fā)現(xiàn)了兩個(gè)比較大的問(wèn)題:

    第一個(gè)是在Windows 7 x64上提示攝像頭初始化失敗的問(wèn)題。這個(gè)問(wèn)題很奇怪,電腦剛開(kāi)機(jī)的時(shí)候可以順利找到一次攝像頭并正常操作,但是第二次就會(huì)提示攝像頭初始化失敗。有人提出的解決方法是安裝一個(gè)叫ManyCamera的程序,這個(gè)程序可以把一個(gè)攝像頭供多個(gè)程序同時(shí)使用,其實(shí)就等于中間加了一層轉(zhuǎn)換,效果會(huì)有點(diǎn)差別,免費(fèi)版還會(huì)加上水印,要求比較高的人可能會(huì)不爽,但是目前找不到其他辦法。

    第二個(gè)是在程序中找不到攝像頭,不光找不到攝像頭,其他媒體設(shè)備通通找不到,使用以下語(yǔ)句:
    vector = CaptureDeviceManager.getDeviceList ( null )
    按照文檔說(shuō)明是返回所有媒體設(shè)備,但每次vector都是null。
    在Eclipse中運(yùn)行又能正常,導(dǎo)出成jar之后運(yùn)行就會(huì)找不到攝像頭。
    原因在于找不到j(luò)mf.properities文件,該文件包含所有檢測(cè)到的媒體設(shè)備的信息,最簡(jiǎn)單的解決方法就是把JMF安裝目錄下lib子目錄中的jmf.properties文件復(fù)制到最后運(yùn)行的jar所在的目錄,不過(guò)如果攝像頭改過(guò)的話,重新檢測(cè)后要把新的文件復(fù)制到j(luò)ar目錄,因?yàn)闄z測(cè)到的媒體設(shè)備信息都會(huì)存放在JMF安裝目錄里面的jmf.properties文件里。

    StackOverflow里面有個(gè)人對(duì)這個(gè)問(wèn)題解釋得比較清楚:
    http://stackoverflow.com/questions/8768142/java-capturedevicemanagergetdevicelist-is-empty


    雖然問(wèn)題解決了,但是還是不明白為何在Eclipse中可以正常運(yùn)行,導(dǎo)出jar后運(yùn)行卻找不到攝像頭,即使把JMF所有jar和lib目錄都加入系統(tǒng)的CLASSPATH環(huán)境變量里還是不行。


    另外,JMF安裝程序會(huì)自動(dòng)把它的jar和lib目錄加入系統(tǒng)的%CLASSPATH%環(huán)境變量,但是如果你卸載了再重新安裝到其他目錄,并不會(huì)改變%CLASSPATH%的值,需要手動(dòng)修改。不過(guò)這個(gè)環(huán)境變量似乎沒(méi)啥用處。
    最好不要把JMF安裝到默認(rèn)的Program Files目錄,可能會(huì)運(yùn)行不了,安裝到短目錄會(huì)比較保險(xiǎn),它似乎還是只認(rèn)Dos時(shí)代的8.3目錄結(jié)構(gòu),但偏偏又默認(rèn)安裝到Program Files里面。
    posted @ 2014-07-01 10:33 amp@java 閱讀(7275) | 評(píng)論 (0)編輯 收藏

    其實(shí)我也搞不懂Windows的域,反正能用就行了。
    但是最近有一臺(tái)客戶(hù)端的時(shí)間改不了,總是提示特權(quán)級(jí)不夠,按理說(shuō)應(yīng)該是組策略限制了,但是我把那臺(tái)計(jì)算機(jī)從包含該組策略的OU中移出來(lái),還是不行,這就奇怪了,難道組策略不是指針對(duì)OU里面的成員的嗎?百思不得其解啊,最后只能在BIOS里面把時(shí)間改了。
    今天發(fā)現(xiàn)我自己的電腦設(shè)置不了屏幕保護(hù),也是組策略限制了,然后把我的用戶(hù)和計(jì)算機(jī)都移出了組策略應(yīng)用的OU,結(jié)果發(fā)現(xiàn)還是設(shè)置不了,這下肯定是組策略的應(yīng)用上有問(wèn)題了。
    搜索了半天發(fā)現(xiàn)有個(gè)叫rsop.msc的管理工具,可以看到某用戶(hù)在某計(jì)算機(jī)上應(yīng)用的組策略,結(jié)果發(fā)現(xiàn)我還是應(yīng)用之前的組策略,但是計(jì)算機(jī)配置和用戶(hù)配置前面都有個(gè)紅叉,右鍵-屬性-錯(cuò)誤信息里面顯示:
    Title
    由于下面列出的錯(cuò)誤,組策略結(jié)構(gòu) 失敗。

    系統(tǒng)找不到指定的路徑。

    注意: 由于 GP Core 失敗,其它組策略組件沒(méi)有一個(gè)處理了它們的策略。因此,其它組件的狀態(tài)信息不可用。
    好像是有某個(gè)組策略找不到,所以不能應(yīng)用的意思。
    然后想起來(lái)在域名下面有個(gè)“新建組策略”,但是沒(méi)有做過(guò)任何配置,應(yīng)該是有人手賤點(diǎn)了一下新建按鈕加進(jìn)去的,于是把它刪除,還是不行。
    重啟了一下客戶(hù)端,居然好了,時(shí)間也可以改了,屏幕保護(hù)也可以改了,一切都按計(jì)劃進(jìn)行。


    莫名其妙~~
    posted @ 2014-06-23 16:11 amp@java 閱讀(1347) | 評(píng)論 (0)編輯 收藏

    現(xiàn)在的手機(jī)攝像頭動(dòng)輒幾百萬(wàn)上千萬(wàn)像素,如果電腦需要用到攝像頭又沒(méi)有的話,不妨用手機(jī)的攝像頭代替。

    我是在做一個(gè)電腦二維碼識(shí)別器的時(shí)候,因?yàn)樵瓉?lái)的攝像頭太差,從而想到用一臺(tái)淘汰的Android手機(jī)來(lái)代替。

    這類(lèi)應(yīng)用應(yīng)該不少,我首先找到的是一個(gè)叫DraoidCam的應(yīng)用,裝好之后發(fā)現(xiàn)免費(fèi)版沒(méi)法調(diào)整分辨率,于是放棄之。

    然后又找到了一個(gè)國(guó)內(nèi)做的免費(fèi)軟件,叫魅色,非常簡(jiǎn)單,支持USB和WiFi連接方式,如果是USB連接的話,打開(kāi)USB調(diào)試模式之后,運(yùn)行電腦的客戶(hù)端,手機(jī)上就自動(dòng)裝上了App并且自動(dòng)運(yùn)行,可以調(diào)整分辨率,不過(guò)最高只有640*480,幀率不到10,不過(guò)已經(jīng)能夠滿足我的需求了。

    然后就可以像普通PC攝像頭一樣使用了,在JMF里面也能找到,于是就可以被Java調(diào)用了。經(jīng)測(cè)試,效果比原來(lái)的PC攝像頭好多了。

    軟件主頁(yè):http://www.libfetion.org/meise/
    posted @ 2014-06-05 15:35 amp@java 閱讀(1722) | 評(píng)論 (4)編輯 收藏

         摘要: TabActivity在API 13(Android 3.2)被標(biāo)記為過(guò)期,需要使用Fragment來(lái)實(shí)現(xiàn),F(xiàn)ragment是Android 3.0引入的一個(gè)概念,主要就是為了適應(yīng)各種不同的屏幕大小(手機(jī)、平板電腦)。Android 4.1發(fā)布時(shí),google還發(fā)布了一個(gè)Android Support v4的包,用于Android 1.6以上的系統(tǒng)兼容新的特性,其中包括Fragment。為了在低于...  閱讀全文
    posted @ 2012-12-27 19:07 amp@java 閱讀(15645) | 評(píng)論 (0)編輯 收藏

    SQL Server 2000的導(dǎo)入導(dǎo)出功能還是不錯(cuò)的,支持各種各樣的數(shù)據(jù)庫(kù),但是卻有好多奇怪的bug,不能直接操作,幾乎每一步都要上網(wǎng)搜索,最后搞定了,一定要記下來(lái):
    1、在同一臺(tái)電腦上裝好SQL Server 2000的客戶(hù)端和Oracle 10g的客戶(hù)端,并分別設(shè)置好到源數(shù)據(jù)庫(kù)(SQL Server 2000數(shù)據(jù)庫(kù))和目標(biāo)數(shù)據(jù)庫(kù)(Oracle 數(shù)據(jù)庫(kù))的連接,兩個(gè)數(shù)據(jù)庫(kù)都有圖形界面的企業(yè)管理器,很容易設(shè)置好;
    2、在控制面板-管理工具-數(shù)據(jù)源里添加一個(gè)DSN,驅(qū)動(dòng)程序選擇類(lèi)似“Oracle in OraClient10g_home1”的,確定之后輸入Data Source Name(隨意),Description(隨意),TNS Service Name(在企業(yè)管理器里設(shè)置好的連接名),User ID(用戶(hù)名),然后按Test Connection測(cè)試是否連接成功,成功之后點(diǎn)OK;
    3、在SQL Server 2000的企業(yè)管理器里,在任意一個(gè)表上點(diǎn)右鍵,所有任務(wù),導(dǎo)出數(shù)據(jù),在目的里選擇“Oracle in OraClient10g_home1”,用戶(hù)/系統(tǒng)DSN里面就會(huì)出現(xiàn)剛才設(shè)置好的DSN名字,選中,然后輸入用戶(hù)名密碼,點(diǎn)兩次下一步就會(huì)出現(xiàn)選擇源表和視圖對(duì)話框
    4、這里要注意的是,勾上源中的某個(gè)表,在目的里面就會(huì)出現(xiàn)"用戶(hù)名"."表名"的默認(rèn)選項(xiàng),如果你剛才使用的Oracle用戶(hù)名是小寫(xiě)的話,這里也會(huì)是小寫(xiě),一定要改成大寫(xiě),否則會(huì)提示該用戶(hù)名不存在

    目的也可以使用Microsoft OLE DB Provider for Oracle,在屬性里面設(shè)置服務(wù)器名稱(chēng)為Oracle的TNS名稱(chēng),用戶(hù)名和密碼輸入Oracle用戶(hù)名和密碼,測(cè)試連接通過(guò)即可,后面的步驟都一樣。

    如果出現(xiàn)以下錯(cuò)誤:

    OLE DB 提供程序 'MSDAORA' 報(bào)錯(cuò)。

    [OLE/DB provider returned message: 未找到 Oracle 客戶(hù)端和網(wǎng)絡(luò)組件。這些組件是由 Oracle 公司提供的,是 Oracle 8i (或更高) 客戶(hù)軟件安裝的一部分。

     

    在安裝這些組件之前,將無(wú)法使用此提供程序。]

    OLE DB 錯(cuò)誤跟蹤[OLE/DB Provider 'MSDAORA' IDBInitialize::Initialize returned 0x80004005:  


    就要修改注冊(cè)表,有人已經(jīng)作出了詳細(xì)的修改說(shuō)明,在這里可以看到:
    http://www.cnblogs.com/autumn/articles/splinkedserver.html

    我把那個(gè)表也貼在這里:
    Oracle Client  Microsoft Windows NT、
    Oracle Microsoft Windows 95、
    Client Windows 98 和 Windows 98 SE
    Microsoft Windows 2000/XP/2003
    7.x [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\TransactionServer\Local Computer\My Computer]
    "OracleXaLib"="xa73.dll"
    "OracleSqlLib"="SQLLib18.dll"
    "OracleOciLib"="ociw32.dll

     

    [HKEY_LOCAL_MACHINE\SOFTWARE
    Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="xa73.dll"
     "OracleSqlLib"="SQLLib18.dll"
     "OracleOciLib"="ociw32.dll"
     
    8.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="xa80.dll"
    "OracleSqlLib"="sqllib80.dll"
    "OracleOciLib"="oci.dll"
     
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
     "OracleXaLib"="xa80.dll"
     "OracleSqlLib"="sqllib80.dll"
    "OracleOciLib"="oci.dll"
    8.1 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient8.dll"
    "OracleSqlLib"="orasql8.dll"
    "OracleOciLib"="oci.dll"
     
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient8.dll"
    "OracleSqlLib"="orasql8.dll"
    "OracleOciLib"="oci.dll"
     
    9.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient9.dll"
    "OracleSqlLib"="orasql9.dll"
    "OracleOciLib"="oci.dll"
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient9.dll"
    "OracleSqlLib"="orasql9.dll"
    "OracleOciLib"="oci.dll"
     
    10.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient10.dll"
    "OracleSqlLib"="orasql10.dll"
    "OracleOciLib"="oci.dll"
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient10.dll"
    "OracleSqlLib"="orasql10.dll"
    "OracleOciLib"="oci.dll"
     
    posted @ 2012-04-28 10:22 amp@java 閱讀(2565) | 評(píng)論 (0)編輯 收藏

    當(dāng)讀寫(xiě)二進(jìn)制文件,或者要把非標(biāo)準(zhǔn)長(zhǎng)度的整數(shù)與標(biāo)準(zhǔn)長(zhǎng)度的整數(shù)互相轉(zhuǎn)換時(shí),就要用到大量的位操作,雖然看起來(lái)很簡(jiǎn)單,實(shí)際上里面卻有很多細(xì)節(jié)很容易出錯(cuò)。

    首先,Java有些標(biāo)準(zhǔn)跟C/C++是不同的:

    1、Java采用高字節(jié)在前的方式讀寫(xiě)數(shù)據(jù),例如要把一個(gè)4字節(jié)的int數(shù)值寫(xiě)入文件時(shí),它是按照從高字節(jié)到低字節(jié)的順序?qū)懭氲模x取的時(shí)候也是這樣讀出來(lái)。
    而C/C++則采用平臺(tái)相關(guān)的方式,在Windows平臺(tái)采用低字節(jié)在前的方式,在Linux/Unix平臺(tái)則采用高字節(jié)在前的方式。
    如果Java要讀取C/C++創(chuàng)建的二進(jìn)制文件,就要注意這個(gè)問(wèn)題,最好先搞清楚原來(lái)的文件是采用哪種方式創(chuàng)建的。網(wǎng)絡(luò)通信也要注意。

    2、Java沒(méi)有無(wú)符號(hào)數(shù),無(wú)論byte,short,int,long都是有符號(hào)整數(shù),而C/C++有個(gè)unsigned關(guān)鍵字可以設(shè)置一個(gè)數(shù)值為無(wú)符號(hào)數(shù)。

    3、Java的整數(shù)基本數(shù)據(jù)類(lèi)型就是byte,short,int,long這幾個(gè),長(zhǎng)度分別為1,2,4,8字節(jié),C/C++可以用typedef定義各種數(shù)據(jù)類(lèi)型。

    第二,Java是采用補(bǔ)碼來(lái)存放整數(shù)的。
    有時(shí)候覺(jué)得補(bǔ)碼的定義有些奇怪,實(shí)際上可以這樣理解:

    把一個(gè)整數(shù)從0一直往上加1,加到溢出就變成了負(fù)數(shù)的最小值,然后再繼續(xù)加1,最后又能回到0,實(shí)際上就是一個(gè)輪回。
    例如一個(gè)byte類(lèi)型的整數(shù),一共有8位,能表示256個(gè)數(shù)值,采用補(bǔ)碼的話數(shù)值范圍就是-128~127,表示方法如下:
    0        0000 0000
    1        0000 0001
    .
    .
    126    0111 1110
    127    0111 1111
    -128   1000 0000
    -127   1000 0001
    .
    .
    -1       1111 1111
    0         0000 0000

    第三、不同長(zhǎng)度的整數(shù)轉(zhuǎn)換。
    如果是從較短的數(shù)轉(zhuǎn)成較長(zhǎng)的數(shù),很簡(jiǎn)單,如果是正數(shù)就在高字節(jié)補(bǔ)0,如果是負(fù)數(shù)就在高字節(jié)補(bǔ)1。
    例如byte的127轉(zhuǎn)為short的127:
    byte:0111 1111
    short:0000 0000 0111 0111
    byte的-127轉(zhuǎn)為short的-127
    byte:1000 0001
    short:1111 1111 1000 0001
    如果是從較長(zhǎng)的數(shù)轉(zhuǎn)成較短的數(shù),實(shí)際上就是把高位都截?cái)嗔耍赞D(zhuǎn)出來(lái)的數(shù)值可能完全不是一回事了。
    例如short的256轉(zhuǎn)為byte:
    short:0000 0001 0000 0000
    byte: 0000 0000
    把256變成了0
    short的-255轉(zhuǎn)成byte:
    short:1111 1111 0000 0001
    byte:0000 0001
    把-255變成了1

    第四、位運(yùn)算操作符及它們的優(yōu)先級(jí)
    Java的位運(yùn)算操作符包括:~非,|按位或,&按位與,^按位異或,<<左移,>>右移,>>>右移左側(cè)補(bǔ)0
    各種運(yùn)算符的優(yōu)先級(jí)如下表所示:
    優(yōu)先級(jí)
    運(yùn)算符
    結(jié)合性
    1
    () [] .
    從左到右
    2
    ! +(正) -(負(fù)) ~ ++ --
    從右向左
    3
    * / %
    從左向右
    4
    +(加) -(減)
    從左向右
    5
    << >> >>>
    從左向右
    6
    < <= > >= instanceof
    從左向右
    7
    == !=
    從左向右
    8
    &(按位與)
    從左向右
    9
    ^
    從左向右
    10
    |
    從左向右
    11
    &&
    從左向右
    12
    ||
    從左向右
    13
    ?:
    從右向左
    14
    = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
    從右向左
    根據(jù)該表可以看到,位運(yùn)算操作符的優(yōu)先級(jí)各有不同,分別為:
    1、~
    2、>> << >>>
    3、&
    4、^
    5、|
    另外需要特別注意的是,除了~,其他位運(yùn)算操作的優(yōu)先級(jí)都低于加減,所以要記得以下語(yǔ)句是返回32而不是7!
    1<<2+3
    還有就是&、^、|的優(yōu)先級(jí)都是低于邏輯操作符的,因此下面的語(yǔ)句會(huì)編譯出錯(cuò),幸好Java不像C那樣對(duì)所有大于1的值都認(rèn)為是真,否則下面的語(yǔ)句也能編譯通過(guò),但可能與你的意圖不太一樣,可能調(diào)試半天才發(fā)現(xiàn)。
    if(3&1>0)
    如果記不清楚,還是按照你的意圖加上括號(hào)最保險(xiǎn)。

    第五、字節(jié)數(shù)組與整數(shù)之間的轉(zhuǎn)換
    為了把一個(gè)整數(shù)存入文件,或者從文件中讀取一個(gè)整數(shù),需要經(jīng)常在字節(jié)數(shù)組和整數(shù)之間轉(zhuǎn)換,這個(gè)過(guò)程要用到大量的位運(yùn)算。
    首先需要記住的是,在參與所有運(yùn)算前,Java都會(huì)把byte、short類(lèi)型的值都轉(zhuǎn)換成int,然后再對(duì)轉(zhuǎn)換后的int進(jìn)行操作。例如下面的語(yǔ)句會(huì)編譯出錯(cuò):
    byte a=10,b=20,c;
    c=a+b;

    因?yàn)閍和b在相加前都被轉(zhuǎn)成了int,最后得到的結(jié)果是個(gè)int類(lèi)型的值,如果要賦給byte類(lèi)型的c,必須顯式地進(jìn)行類(lèi)型轉(zhuǎn)換,即把第二句改為:
    c=(byte)(a+b)

    這一點(diǎn)很關(guān)鍵,因?yàn)閷?duì)于一個(gè)最高位為1的byte類(lèi)型的整數(shù)(負(fù)數(shù)),在運(yùn)算之前它會(huì)被強(qiáng)制轉(zhuǎn)換成int類(lèi)型,根據(jù)上面所說(shuō)的第三點(diǎn),其實(shí)就是往前面的三個(gè)高字節(jié)補(bǔ)上1,這樣一來(lái),它在參與位運(yùn)算的過(guò)程中,就不僅僅是它本身的8個(gè)bit參與了,實(shí)際上連前3個(gè)字節(jié)的24個(gè)bit(均為1)也參與了。例如有一個(gè)整數(shù)i=1082163328,它的二進(jìn)制表示為:
    01000000 10000000 10000000 10000000
    分為4個(gè)字節(jié)存儲(chǔ),除了第一個(gè)字節(jié)是正數(shù)外,其余3個(gè)字節(jié)均為負(fù)數(shù)。假如用a代表最高字節(jié)的值,用b代表其他三個(gè)字節(jié)的值,如果按照通常的理解,你可能會(huì)這樣得到i的值:
    i=(a<<24)+(b<<16)+(b<<8)+b

    如果a和b都是正數(shù),上面的等式是成立的,但是在這個(gè)例子里,卻是錯(cuò)的,因?yàn)樯鲜街械腶和b都已經(jīng)被強(qiáng)制轉(zhuǎn)換成了int類(lèi)型再參加運(yùn)算,實(shí)際上
    a=00000000 00000000 00000000 01000000
    b=11111111 11111111 11111111 10000000
    i=01000000 00000000 00000000 00000000+11111111 10000000 00000000 00000000+11111111 11111111 10000000 00000000+11111111 11111111 11111111 10000000
    最后得到的結(jié)果是1065320320,不是原來(lái)的值了。
    為了不讓byte在強(qiáng)制轉(zhuǎn)換成int的過(guò)程加入了我們不想要的高位1,我們需要把它跟0xff進(jìn)行與操作,i的值應(yīng)該這樣運(yùn)算:
    = ( ( a& 0xff ) << 24 ) +( ( b & 0xff ) << 16 ) + ( ( b & 0xff ) << 8 ) + ( b & 0xff )

    注意,因?yàn)?amp;和<<的優(yōu)先級(jí)都低于+,所以上面的括號(hào)是不能少的。不過(guò)由于跟0xff與操作之后,其余24位都變成了0,因此可以把+改為|操作,因?yàn)槿魏沃蹬c0進(jìn)行或操作都得到本身:
    = ( a & 0xff ) << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )

    由于<<的優(yōu)先級(jí)高于|,所以省了一些括號(hào)。最高字節(jié)可以不與0xff進(jìn)行與操作,因?yàn)樗D(zhuǎn)換成int后左邊增加的3個(gè)字節(jié)都在左移24位時(shí)被去掉了:
    = a << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )


    把int轉(zhuǎn)為字節(jié)數(shù)組的時(shí)候比較簡(jiǎn)單,直接右移截?cái)嗉纯桑?/span>
    byte[] b = new byte[4];
    b[0= (byte) (i >> 24);
    b[1= (byte) (i >> 16);
    b[2= (byte) (i >> 8);
    b[3= (byte) i;


    第六、非標(biāo)準(zhǔn)長(zhǎng)度整數(shù)的存儲(chǔ)和讀取
    假如有兩個(gè)變量,他們的值可以用12個(gè)bit來(lái)表示,如果我們用16bit的short類(lèi)型來(lái)表示一個(gè)變量,那么兩個(gè)變量就需要4個(gè)字節(jié),而實(shí)際上它們只需要3個(gè)字節(jié)就能表示出來(lái),如果存儲(chǔ)空間比較有限,寫(xiě)入文件時(shí)可以把它們存放在3個(gè)字節(jié)里面,但是讀寫(xiě)過(guò)程就需要進(jìn)行轉(zhuǎn)換。
    在內(nèi)存里,它們都是標(biāo)準(zhǔn)的數(shù)據(jù)類(lèi)型:
    short a,b;

    寫(xiě)入文件時(shí),我們用第一個(gè)字節(jié)和第二個(gè)字節(jié)的前半部分來(lái)表示a,把第二個(gè)字節(jié)的后半部分和第三個(gè)字節(jié)來(lái)表示b,即:
    1:xxxx xxxx
    2:xxxx yyyy
    3:yyyy yyyy
    x和y都表示一個(gè)bit,分別用來(lái)存放a和b。寫(xiě)入時(shí)先把a(bǔ)和b轉(zhuǎn)為字節(jié)數(shù)組:
    byte[] out = new byte[3];
    out[
    0= (byte) ( a >> 4 );//把a(bǔ)的高8位放在第一個(gè)字節(jié)
    out[1= (byte) ( a << 4 );//先把a(bǔ)左移四位,在右邊補(bǔ)上4個(gè)0,第二個(gè)字節(jié)的高4位就是a的低4位了,第二個(gè)字節(jié)的高4位已經(jīng)生成,低4位還是0
    out[1|= (byte) ( b >> 8 & 0x0f );//b右移8位,并與0x0f進(jìn)行與操作,實(shí)際上就只保留了b的高4位,并且是在字節(jié)的低4位上,跟第二步得到的字節(jié)進(jìn)行或操作,就生成了第二個(gè)字節(jié)
    out[2= (byte) b;//把b的高4位截?cái)嗑偷玫搅说?位
    然后再把這個(gè)字節(jié)數(shù)組寫(xiě)入文件,就可以用3個(gè)字節(jié)表示兩個(gè)整數(shù)了。
    讀取:
    =(short)( (out[0& 0xff<< 4 | ( out[1& 0xf0 )>>4);
    = (short)((out[1& 0x0f<< 8 | ( out[2& 0xff));
    posted @ 2012-04-08 16:56 amp@java 閱讀(1840) | 評(píng)論 (2)編輯 收藏

    AdMob是往手機(jī)應(yīng)用程序里添加廣告的最流行的方式,Android程序基本都是靠這個(gè)賺錢(qián)。看文檔似乎很簡(jiǎn)單,但是操作起來(lái)卻不是那么回事,今天搞了一上午才弄明白怎么正確添加,網(wǎng)上搜索到的資料都不適合最新的SDK。

    按照AdMob的官方文檔,很簡(jiǎn)單,只要把AdMob的開(kāi)發(fā)包jar放到Build Path的Libraries里面就行了,這樣做編譯是沒(méi)問(wèn)題的,但是一運(yùn)行就會(huì)出錯(cuò),提示
    java.lang.NoClassDefFoundError:com.google.ads.AdView
    這是因?yàn)镚oogle最近更新了ADT到17.0,改變了項(xiàng)目依賴(lài)的檢測(cè)方式,官方的說(shuō)明在這里,不過(guò)看得不是很懂。有人用圖形的方式標(biāo)了出來(lái),容易理解一些,看這里。如果不求甚解,就把剛才放到Build Path里面的jar移除,直接在項(xiàng)目目錄下建立一個(gè)libs目錄,然后把那個(gè)jar文件放進(jìn)去就行了。

    AdMob SDK也更新到了4.3.1,網(wǎng)上搜索到的在XML文件里面設(shè)置AdView屬性的方法也已過(guò)時(shí),現(xiàn)在不需要建立attrs.xml文件,直接增加一個(gè)
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    就可以在AdView標(biāo)簽里面設(shè)置ads開(kāi)頭的屬性了,關(guān)于xml設(shè)置AdView屬性的官方文檔隱藏得比較深,沒(méi)有在目錄中列出來(lái),只能在其他文檔里面的鏈接里進(jìn)去,在這里
    另外,按照官方說(shuō)明,要在AndroidManifest.xml里面添加一個(gè)Activity的聲明:
        <activity android:name="com.google.ads.AdActivity"
                  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
    后面那個(gè)屬性android:configChanges的最后兩個(gè)值screenSize|smallestScreenSize是在Android 3.2后面才增加的,這兩個(gè)值必須填上去,否則運(yùn)行的時(shí)候會(huì)報(bào)錯(cuò)。如果你使用的SDK是3.2以下的,識(shí)別不了這兩個(gè)值,編譯也不會(huì)報(bào)錯(cuò)。因此你的項(xiàng)目必須使用Android 3.2以上的SDK,也就是項(xiàng)目根目錄下的project.properties文件里面的屬性target的值必須是android-13以上,例如
    target=android-15
    但是可以在AndroidManifest.xml里面設(shè)置android:minSdkVersion和android:targetSdkVersion為比13低的值,這樣就不需要安裝Android 3.2以上的手機(jī)或平板來(lái)運(yùn)行這個(gè)程序,實(shí)際上AdMob支持Android 1.5以上的系統(tǒng),只是開(kāi)發(fā)需要更高版本的SDK而已。


    這次折騰讓我真正體會(huì)到Android更新得實(shí)在太快了,連官方的文檔都來(lái)不及更新,開(kāi)發(fā)人員只能自己摸索總結(jié),幸好有強(qiáng)大的搜索工具,只要你遇到的問(wèn)題不是第一個(gè),就會(huì)有人找到解決方案。



    posted @ 2012-03-25 19:23 amp@java 閱讀(3705) | 評(píng)論 (7)編輯 收藏

    SWT里TableEditor的作用是可以在表格里面顯示一些控件,例如列表、按鈕等,有時(shí)候是根據(jù)表格的內(nèi)容在控件上顯示不同內(nèi)容的,如果更新了表格內(nèi)容,就要同時(shí)更新控件,但是表格內(nèi)容可以通過(guò)Table控件的removeAll()來(lái)清除,而表格中的控件則無(wú)法用這個(gè)方法清除,你調(diào)用Table的removeAll()方法,往表格里填入新內(nèi)容后,控件還是上次的控件,但是你一操作那些控件就會(huì)出異常,提示那些控件已經(jīng)disposed。

    解決方法是顯式地調(diào)用控件及TableEditor的dispose()方法,在你建立TableEditor的時(shí)候,把它的引用保存起來(lái),把里面的控件的引用也保存起來(lái),到整個(gè)表格需要的清除的時(shí)候,通過(guò)引用先把控件dispose掉,再把TableEditor也dispose掉,這樣整個(gè)表格的內(nèi)容就真正清除了。

    例如有一個(gè)表格名為table,里面的每一行都有3列,第一列是文本,第二列是Combo,第三列是Button,繪制表格的時(shí)候是這樣的:

    TableItem ti = new TableItem(table,SWT.NONE);
    ti.setText(
    0,"some string");
    te 
    = new TableEditor(table);
    Combo combo 
    = new Combo(table,SWT.NONE);
    controls.add(combo);
    te.setEditor(combo,ti,
    1);
    Button button 
    = new Button(table,SWT.NONE);
    controls.add(button);
    te.setEditor(button,ti,
    2);

    其中te和controls都是成員變量,te的類(lèi)型是TableEditor,controls的類(lèi)型是ArrayList<Control>。
    當(dāng)整個(gè)table要清除內(nèi)容時(shí),可以這樣:
    //刪除控件
    for(Control control:controls){
    control.dispose();
    }
    //刪除TableEditor
    te.dispose();
    //刪除文本
    table.removeAll();
    posted @ 2012-03-09 11:09 amp@java 閱讀(3850) | 評(píng)論 (0)編輯 收藏

    mars課程里關(guān)于Socket通信那一課說(shuō)那些程序只能在真機(jī)上運(yùn)行,模擬器模擬不了,實(shí)際上是可以的。
    Android模擬器是通過(guò)一個(gè)類(lèi)似路由器的虛擬網(wǎng)絡(luò)層與電腦相連,可以看作模擬器是處于“內(nèi)網(wǎng)”當(dāng)中,每個(gè)模擬器都有自己的虛擬路由器,而且虛擬路由器的地址總是10.0.2.1,在模擬器看來(lái),電腦的地址是10.0.2.2,模擬器自己的地址是10.0.2.15,無(wú)論你啟動(dòng)多少個(gè)模擬器,對(duì)于模擬器來(lái)說(shuō)都是這樣的地址,模擬器之間不能直接通信。
    啟動(dòng)模擬器的時(shí)候,電腦會(huì)給模擬器分配兩個(gè)端口,通過(guò)這兩個(gè)端口,電腦就能操作模擬器。第一個(gè)啟動(dòng)的模擬器的端口是5554和5555,第二個(gè)是5556和5557,以此類(lèi)推,最多可以同時(shí)啟動(dòng)32個(gè)模擬器。第一個(gè)端口(偶數(shù)端口)可以接受telnet連接,對(duì)模擬器進(jìn)行設(shè)置,第二個(gè)端口(奇數(shù)端口)則接受adb連接,可以用來(lái)調(diào)試。第一個(gè)端口可以在模擬器窗口的標(biāo)題欄看到,如下圖所示:

    5554表示端口號(hào),t表示模擬器名稱(chēng)。
    實(shí)際上,這些端口也是電腦監(jiān)聽(tīng)的端口,在電腦上通過(guò)netstat可以看到本機(jī)正在監(jiān)聽(tīng)這些端口,因此通過(guò)telnet localhost 5554就能連上第一臺(tái)模擬器,連上之后通過(guò)help命令可以查看操作幫助。
    為了實(shí)現(xiàn)電腦和模擬器上的android程序進(jìn)行socket通信,需要把程序開(kāi)啟的端口通過(guò)端口映射設(shè)置到電腦上,這跟家里的路由器端口映射概念是一樣的。telnet到模擬器之后,通過(guò)
    redir add tcp:1234:1234
    就能把模擬器上的1234端口映射到電腦上,第一個(gè)表示電腦端口,第二個(gè)表示模擬器程序要使用端口,這兩個(gè)數(shù)字可以相同也可以不同,要映射udp端口就把tcp改為udp即可
    redir add udp:1234:1234
    這樣一來(lái),當(dāng)模擬器的程序打開(kāi)1234端口時(shí),在電腦上也打開(kāi)了對(duì)應(yīng)的端口,只要通過(guò)電腦連接127.0.0.1的對(duì)應(yīng)端口,就連上了模擬器的程序端口,就可以通過(guò)電腦上的client向模擬器的server發(fā)送數(shù)據(jù),不需要通過(guò)真機(jī)運(yùn)行。
    如果要讓第一個(gè)模擬器向第二個(gè)模擬器發(fā)送數(shù)據(jù),也可以把第二個(gè)模擬器的端口映射到電腦上,然后在第一個(gè)模擬器程序中向10.0.2.2的對(duì)應(yīng)端口發(fā)送數(shù)據(jù)即可。


    模擬器還有一個(gè)很有意思的功能,每個(gè)模擬器默認(rèn)的電話號(hào)碼就是它的第一個(gè)端口號(hào),例如開(kāi)了兩個(gè)模擬器,第一個(gè)撥打5556,第二個(gè)就會(huì)顯示5554來(lái)電,還能接通,發(fā)短信也可以,這樣就能模擬電話和短信功能。

    詳細(xì)的信息可以看Dev Guide的模擬器部分:http://developer.android.com/guide/developing/devices/emulator.html
    posted @ 2012-02-24 10:37 amp@java 閱讀(2413) | 評(píng)論 (0)編輯 收藏

    前天是情人節(jié),雖然結(jié)婚好多年了,但是老婆一直都喜歡驚喜的浪漫,可惜我卻是個(gè)木訥的呆子,做不出那些轟動(dòng)的事情。那天下午馬上就要下班回家了,突然在微博上看到有人談到geek的情人節(jié)禮物,雖然我不是geek,但是最近在學(xué)Android,老婆的手機(jī)也是Android系統(tǒng)的,何不專(zhuān)門(mén)做個(gè)程序給她?

    想法可嘉,但是動(dòng)起手來(lái)卻不是那么回事。學(xué)了那么多天,真正派上用場(chǎng)的還沒(méi)學(xué)到。時(shí)間只剩下不到一個(gè)小時(shí)了,我會(huì)的只是在屏幕上顯示幾個(gè)大字:XXX,我愛(ài)你!

    后來(lái)想想似乎太單調(diào),如果能夠加上點(diǎn)背景音樂(lè)可能好點(diǎn),但是還沒(méi)學(xué)會(huì)怎么使用,上網(wǎng)搜了一下,幸好很簡(jiǎn)單,用MediaPlayer就可以了,幾條語(yǔ)句就能搞定。音樂(lè)文件怎么來(lái)呢?通過(guò)網(wǎng)絡(luò)在線播放是最簡(jiǎn)單的,于是就到百度MP3搜了一下“情人節(jié)快樂(lè)”,我記得有一首歌里面一直在喊“情人節(jié)快樂(lè)”的,結(jié)果最后發(fā)現(xiàn)那首歌名字叫《沒(méi)有情人的情人節(jié)》……

    算了,管它呢,有老婆就行了,沒(méi)有情人照樣過(guò)情人節(jié),打開(kāi)發(fā)現(xiàn)鏈接居然是百度的,以前百度不是說(shuō)它只負(fù)責(zé)搜索,不負(fù)責(zé)存放嗎,怎么現(xiàn)在的MP3都放在百度的服務(wù)器了?把鏈接復(fù)制下來(lái),在模擬器上運(yùn)行還是挺好的,因?yàn)樗玫氖请娔X的寬帶,呵呵。不過(guò)過(guò)了一會(huì)提示下載失敗,把那個(gè)地址往瀏覽器一貼,果然打不開(kāi)了,原來(lái)百度這種下載鏈接是有有效期的,只能讓你試聽(tīng)一下,然后下載,不是長(zhǎng)期有效的。這就麻煩了,到時(shí)候裝在手機(jī)上沒(méi)聲音豈不是很糗?

    再搜索一下,還好,可以把MP3文件放在assets里面,發(fā)布程序的時(shí)候把它包含在apk里面就行了,不用聯(lián)網(wǎng)了。

    現(xiàn)在可以在顯示大字的同時(shí)播放《沒(méi)有情人的情人節(jié)》了。看了一下效果,還是有點(diǎn)怪異,手機(jī)的狀態(tài)欄和程序的標(biāo)題跟黑色的背景,紅色的大字似乎不太搭配,于是繼續(xù)搜索全屏代碼,哈哈,兩句搞定,這樣炫多了。

    不過(guò)一直看著那幾個(gè)字沒(méi)任何反應(yīng),似乎太單調(diào)了,于是就想讓它們不斷變色,或者動(dòng)一下也好,但是無(wú)論怎么弄都搞不定,下班時(shí)間到了,要去接老婆了,就這樣吧。

    之前都是在模擬器上運(yùn)行,或者接個(gè)USB在手機(jī)上運(yùn)行,還不知道怎么打包成apk呢,這下居然沒(méi)搜索到,可能太簡(jiǎn)單了,大家都沒(méi)說(shuō)。于是在項(xiàng)目上點(diǎn)右鍵,果然看到導(dǎo)出apk的菜單,我選擇了unsigned方式導(dǎo)出,在手機(jī)上居然安裝不了。再搜索一下,哦,原來(lái)是要導(dǎo)出成signed apk才能裝的,但是我沒(méi)有證書(shū),怎么signed呢?沒(méi)想到ADT還可以生成證書(shū),一下就搞定了,這比Symbian那種簽名簡(jiǎn)單多了,但是可能也是導(dǎo)致Android惡意軟件泛濫的原因之一。

    去接老婆的時(shí)候通過(guò)藍(lán)牙把a(bǔ)pk發(fā)到她手機(jī)上,裝上,運(yùn)行,從她表情上看出,我的努力沒(méi)有白費(fèi)。不過(guò)最后還是發(fā)現(xiàn)了個(gè)嚴(yán)重的bug,那首歌還沒(méi)放完,另外一個(gè)聲音已經(jīng)重新開(kāi)始了,形成了“二重唱”的效果,而且程序退出之后還在唱,趕工造成的悲劇啊。

    下面是代碼:
    public class LoveActivity extends Activity {
        TextView text;
        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
            WindowManager.LayoutParams.FLAG_FULLSCREEN);  
            requestWindowFeature(Window.FEATURE_NO_TITLE);  
            setContentView(R.layout.main); 
            MediaPlayer mp 
    = new MediaPlayer();
            
    try{
                AssetManager assetManager 
    = getAssets();
                AssetFileDescriptor afd 
    = assetManager.openFd("a.mp3");
                mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                mp.prepare();
                mp.start();
            }
            
    catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    main.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation
    ="vertical"
        android:layout_width
    ="fill_parent"
        android:layout_height
    ="fill_parent"
        
    >
        
    <TextView 
        
    android:id="@+id/textView1" 
        android:text
    ="@string/loveyou" 
        android:layout_width
    ="match_parent" 
        android:layout_height
    ="match_parent" 
        android:gravity
    ="center" 
        android:textColor
    ="#ff0000"
        android:textStyle
    ="bold"
        android:textSize
    ="50dip"
        
    />
        
       
    </LinearLayout>
    strings.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        
    <string name="hello">Hello World, LoveActivity!</string>
        
    <string name="app_name">Love</string>
        
    <string name="loveyou">XXX\n我愛(ài)你</string>
    </resources>
    再把那首mp3放到assets里,改名為a.mp3即可。




    希望明年能做出個(gè)更好的。
    posted @ 2012-02-16 11:06 amp@java 閱讀(2295) | 評(píng)論 (2)編輯 收藏

    昨天在調(diào)試一段Android程序的時(shí)候發(fā)現(xiàn)總是出現(xiàn)NullPointerException,是來(lái)自一句System.out.println(),但是把里面的內(nèi)容分拆了幾次都找不到哪里有null,最后發(fā)現(xiàn)居然是因?yàn)樽罱K輸出的字符串是null!

    一直以來(lái),在JavaSE里,如果字符串本身是null,System.out.println()打印該字符串,會(huì)在終端輸出“null”,而在Android里卻是直接拋出NullPointerException,整個(gè)程序都會(huì)被終止。

    大家可以測(cè)試一下下面的語(yǔ)句在兩種環(huán)境下的運(yùn)行結(jié)果:
    1 String s = null;
    2 System.out.println(s);
    posted @ 2012-02-13 14:49 amp@java 閱讀(1378) | 評(píng)論 (1)編輯 收藏

    這是mars課程里面關(guān)于handler和線程的一個(gè)例子:
    package mars.handler;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;

    public class HandlerTest extends Activity {
        Handler handler 
    = new Handler();
        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            System.out.println(
    "1");
            handler.post(r);
            System.out.println(
    "2");
            setContentView(R.layout.main);
            System.out.println(
    "activity---->"+Thread.currentThread().getId());
            System.out.println(
    "activity name--->"+Thread.currentThread().getName());
        }
        
        Runnable r 
    = new Runnable() {
            
            @Override
            
    public void run() {
                
    // TODO Auto-generated method stub
                System.out.println("handler---->"+Thread.currentThread().getId());
                System.out.println(
    "handlername---->"+Thread.currentThread().getName());
                
    try {
                    Thread.sleep(
    10000);
                } 
    catch (InterruptedException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(
    "3");
            }
        };
    }

    根據(jù)mars的解釋?zhuān)琱andler所在的線程跟Activity的線程是同一個(gè)線程,所以在
    handler.post(r);
    語(yǔ)句后,執(zhí)行的是Runnable里面的run函數(shù),這個(gè)函數(shù)沒(méi)有在新開(kāi)的線程中執(zhí)行,只是簡(jiǎn)單地調(diào)用了run函數(shù),所以這個(gè)app在模擬器運(yùn)行時(shí)要過(guò)10秒才會(huì)顯示界面,因?yàn)閞un函數(shù)里面睡眠了10秒,等它返回后才執(zhí)行setContentView函數(shù)設(shè)置界面元素。
    根據(jù)實(shí)際運(yùn)行結(jié)果,的確是過(guò)了10秒才能顯示界面。

    但是奇怪的是System.out語(yǔ)句似乎沒(méi)有受到影響,下面是日志:
    log
    02-09 11:12:43.553: INFO/System.out(591): 1
    02-09 11:12:43.553: INFO/System.out(591): 2
    02-09 11:12:43.674: INFO/System.out(591): activity---->1
    02-09 11:12:43.674: INFO/System.out(591): activity name--->main
    02-09 11:12:43.713: INFO/System.out(591): handler---->1
    02-09 11:12:43.713: INFO/System.out(591): handlername---->main
    02-09 11:12:53.775: INFO/System.out(591): 3

    從日志可以看出,除了run函數(shù)里面睡眠后才執(zhí)行的打印函數(shù)推遲了10秒才執(zhí)行之外,其他都是沒(méi)有受到任何延時(shí),順序執(zhí)行的,在
    handler.post(r);
    語(yǔ)句前后的打印函數(shù)都被按順序執(zhí)行了,唯獨(dú)
    setContentView(R.layout.main);
    需要在run函數(shù)返回后才執(zhí)行,這是什么道理?難道打印函數(shù)的優(yōu)先級(jí)更高,不會(huì)堵塞?如果是這樣的話為什么在run函數(shù)里面還是要等睡眠結(jié)束才執(zhí)行呢?
    posted @ 2012-02-09 19:25 amp@java 閱讀(1837) | 評(píng)論 (6)編輯 收藏

    很想搞點(diǎn)Android的小程序玩玩,但是卻萬(wàn)事開(kāi)頭難,不知道從哪里開(kāi)始,看了官方的文檔,結(jié)果一天都看不了幾段,還是英文的,比較痛苦。找了些電子書(shū),也是看過(guò)目錄就不知道放哪里了。這種編程的入門(mén)沒(méi)有強(qiáng)大的決心真的很難靜下心來(lái)學(xué)習(xí)。
    前幾天又心血來(lái)潮,搜索了一下android開(kāi)發(fā)的網(wǎng)站,發(fā)現(xiàn)了一些視頻,看起來(lái)還挺有意思,連續(xù)看了幾個(gè),慢慢地也摸著一點(diǎn)門(mén)路了,以前沒(méi)有試過(guò)用這種方法學(xué)習(xí),都是看書(shū),現(xiàn)在發(fā)現(xiàn)看視頻似乎更高效,起碼眼睛沒(méi)那么累,有人在念,很多時(shí)候只要用耳朵聽(tīng)就行了,而且所有軟件的界面、步驟都很清楚,這些東西通過(guò)書(shū)是沒(méi)法表現(xiàn)出來(lái)的。
    現(xiàn)在學(xué)會(huì)了讓一個(gè)Activity顯示出來(lái),放上點(diǎn)控件,處理一下點(diǎn)擊,頁(yè)面布局等,算是入門(mén)了,但很多東西還要繼續(xù)看,那些視頻還有好多。
    入門(mén)系列視頻地址:
    http://www.marsdroid.org/
    還有一個(gè)深入淺出系列:
    http://www.eoeandroid.com/thread-109361-1-1.html
    由于沒(méi)有入門(mén),所以還在看第一個(gè)系列,第二個(gè)系列只看了兩個(gè)。
    到現(xiàn)在發(fā)現(xiàn)android界面的構(gòu)建很像web界面,android是通過(guò)layout來(lái)排布控件,而web是通過(guò)css,android可以通過(guò)java來(lái)操縱控件,而web則是通過(guò)javascript操縱控件,回調(diào)函數(shù)則跟JavaSE一樣。



    不過(guò)有時(shí)候很容易忘記了一個(gè)步驟導(dǎo)致程序運(yùn)行出錯(cuò),一般來(lái)說(shuō),要讓一個(gè)Activity成功運(yùn)行,需要做以下步驟:
    1、有一個(gè)繼承與Activity的類(lèi)
    2、有一個(gè)layout文件,里面是各種控件的布局,在Activity里面應(yīng)該用setContentView加載這個(gè)layout
    3、有一個(gè)strings文件,里面是界面的各種字符串,用于國(guó)際化
    4、在AndroidManifest里面加入這個(gè)Activity
    第4步很容易忘記。
    posted @ 2012-02-08 14:55 amp@java 閱讀(261) | 評(píng)論 (0)編輯 收藏

    前段時(shí)間聽(tīng)了一家公司介紹分布式存儲(chǔ)產(chǎn)品,號(hào)稱(chēng)性能超過(guò)傳統(tǒng)的磁盤(pán)陣列+小型機(jī),但價(jià)格卻比這種組合低,而且具有維護(hù)簡(jiǎn)單、數(shù)據(jù)安全等優(yōu)點(diǎn),其核心就是把一些PC服務(wù)器通過(guò)網(wǎng)絡(luò)連接起來(lái),把數(shù)據(jù)分散存儲(chǔ)在這些服務(wù)器上,查找的時(shí)候把任務(wù)分配到這些服務(wù)器上,讓它們分別完成各自的小任務(wù),最后再匯合出結(jié)果,核心就是:每個(gè)節(jié)點(diǎn)都是一個(gè)數(shù)據(jù)存儲(chǔ)單元和運(yùn)算單元的結(jié)合,這些節(jié)點(diǎn)性能要求不高,可以是各種各樣的配置,只要在上面運(yùn)行集群要求的軟件即可,一臺(tái)掛了不要緊,換上去一臺(tái)就能自動(dòng)恢復(fù),增加一臺(tái)就能提高性能,減少一臺(tái)也不會(huì)有很大影響,只是性能稍微下降,每份數(shù)據(jù)都有多個(gè)備份,能夠平衡分布在各服務(wù)器上。這種架構(gòu)的缺點(diǎn)是,只要用上了這套東西,所有的軟件就必須從這家公司購(gòu)買(mǎi),因?yàn)檎麄€(gè)集群的控制和訪問(wèn)接口都是他們提供的。
    該公司也坦言這其實(shí)就是google的服務(wù)器應(yīng)用技術(shù),實(shí)際上就是google提出來(lái)的云計(jì)算。

    今天看了一些文章介紹,發(fā)現(xiàn)上面介紹的東西實(shí)際上已經(jīng)通過(guò)Apache的一個(gè)項(xiàng)目Hadoop實(shí)現(xiàn),不知道那家公司是不是就是簡(jiǎn)單包裝了一下這個(gè)項(xiàng)目。

    Hadoop包含兩個(gè)主要的模塊,分別是HDFS分布式文件系統(tǒng)和MapReduce集群計(jì)算機(jī)制。剛剛發(fā)布了1.0.0版本。

    主頁(yè): http://hadoop.apache.org/

    blogjava有位高手已經(jīng)翻譯了HDFS的架構(gòu)說(shuō)明:http://m.tkk7.com/killme2008/archive/2008/06/05/206043.html,但對(duì)應(yīng)的是上一個(gè)版本0.20的,里面說(shuō)到了很多沒(méi)有實(shí)現(xiàn)的東西,不知道是否已經(jīng)在1.0版本實(shí)現(xiàn),目前官方網(wǎng)站上該文章的版本還是0.20的。

    這里有三篇文章介紹Hadoop在單機(jī)環(huán)境、多機(jī)環(huán)境下的安裝和配置,還有應(yīng)用程序的開(kāi)發(fā):http://www.ibm.com/developerworks/cn/linux/l-hadoop-1/index.html

    看起來(lái)還是挺有意思的,以前就曾經(jīng)有過(guò)想法,把單位淘汰下來(lái)的那一大堆臺(tái)式電腦組成一個(gè)存儲(chǔ)或者計(jì)算的小集群,也許能夠代替一兩臺(tái)PC服務(wù)器,現(xiàn)在看來(lái)可以試試,以后的趨勢(shì)就是云計(jì)算了,先自己搞點(diǎn)小云看看效果如何。
    posted @ 2012-01-19 14:47 amp@java 閱讀(224) | 評(píng)論 (0)編輯 收藏

    這個(gè)不僅僅是IE6的錯(cuò),而是所有IE的錯(cuò)!!
    IE有一個(gè)特別隨意的功能,就是能夠通過(guò)Element的name來(lái)操作一個(gè)Element,有些人覺(jué)得這個(gè)功能很方便,實(shí)際它不僅不符合標(biāo)準(zhǔn),還會(huì)導(dǎo)致IE自己變得莫名其妙。
    假如你的Form有一個(gè)提交按鈕的name="submit",那么,很遺憾,你這個(gè)form無(wú)論如何都不能通過(guò)Javascript來(lái)提交,只要你一調(diào)用了這個(gè)form的submit()方法,IE就會(huì)告訴你它不支持這個(gè)方法!這不是搞笑嗎?哪個(gè)瀏覽器會(huì)不支持form的submit()方法?雖然IE不標(biāo)準(zhǔn),也不至于這樣吧?對(duì)不起,就是這樣。

    因?yàn)楫?dāng)你調(diào)用form的方法submit(),它首先想到的是你的提交按鈕!
    theForm.submit()
    這個(gè)語(yǔ)句在IE看來(lái)并不是調(diào)用theForm的submit方法,而是調(diào)用了名字為submit的提交按鈕!如果你在某個(gè)元素對(duì)象后面加個(gè)括號(hào),會(huì)有什么效果?當(dāng)然就是出錯(cuò)。在IE的獨(dú)特視角下,上面這個(gè)語(yǔ)句與下面這個(gè)語(yǔ)句的效果一樣:
    (theForm.submit)();
    前一個(gè)括號(hào)代表了名稱(chēng)為submit的按鈕對(duì)象,后面那個(gè)括號(hào)就無(wú)法理解了,所以IE告訴你不支持這個(gè)方法。

    IE整個(gè)家族都是如此的丑陋!

    posted @ 2010-12-09 15:02 amp@java 閱讀(292) | 評(píng)論 (0)編輯 收藏

    一直都看到很多人說(shuō),IE6是Web開(kāi)發(fā)人員的惡夢(mèng),以前我單位的內(nèi)部網(wǎng)絡(luò),所有電腦裝的都是IE6,我只針對(duì)IE6開(kāi)發(fā),似乎沒(méi)什么感覺(jué),反正在我的電腦上看到什么樣的,其他電腦上看到也是一樣的。
    后來(lái)因?yàn)槟彻窘o我們做的一個(gè)系統(tǒng)運(yùn)行速度實(shí)在太慢,我把自己的電腦更新到IE8,發(fā)現(xiàn)速度快了很多,但是有些東西不兼容,我對(duì)那些不兼容的功能使用得比較少,就不管了。
    終于,我自己又要開(kāi)發(fā)一個(gè)小項(xiàng)目,用了一個(gè)網(wǎng)上下載的CSS模板,發(fā)現(xiàn)里面很多針對(duì)IE的注釋?zhuān)瑥腎E 5到IE 8都有,反正我電腦上看著效果不錯(cuò),于是就用了。
    辛苦了好幾天,我那項(xiàng)目基本完工了,想在IE6上看看效果,Shit,本來(lái)顯示在頁(yè)面右方主要區(qū)域的表格掉在了左邊導(dǎo)航欄的下面,表格里面一些DIV的下劃線莫名其妙地不見(jiàn)了,這些東西在我的電腦上顯示得好好的,也沒(méi)用到什么特別的東西,怎么差別會(huì)這么大呢?
    一個(gè)個(gè)問(wèn)題排查:
    表格問(wèn)題,在IE6上表現(xiàn)得有些詭異,顯示完之后表格是在下面的,但是鼠標(biāo)晃過(guò)導(dǎo)航欄里面的鏈接,表格又會(huì)自動(dòng)跳到右方區(qū)域,真見(jiàn)鬼。改了一下布局的padding,一個(gè)表格好了。另外一個(gè)卻還是掉下去,仔細(xì)研究了一下,把表格的寬度減少10px,好了。
    下劃線問(wèn)題,我用的是:
    border-bottom:1px solid grey
    結(jié)果IE6不會(huì)顯示出這條下劃線。搜索一下才知道這是IE6的bug,它理解不了這么長(zhǎng)的句子!必須寫(xiě)成這樣:
    border-bottom-width:1px;
    border-bottom-style:solid;
    border-bottom-color:grey;
    還有比這更傻逼的嗎?有!
    它顯示出的線是黑色的,不是grey的!而且根據(jù)DIV里面內(nèi)容的顏色不同,它還會(huì)變色!如果里面是紅色的字,那么它下面的線也是紅色,如果是綠色的字,下面的線也是綠色,如果沒(méi)有指定顏色,它就是黑色,非常智能,但就是不顯示你要的顏色!
    后來(lái)知道原來(lái)它根本不知道grey的意思,必須指定顏色代碼才能解決。


    這就是IE6,沒(méi)想到微軟這么大一個(gè)公司還出了這么一個(gè)垃圾,而且出了那么多年,至今還占據(jù)中國(guó)瀏覽器市場(chǎng)的半壁江山!



    posted @ 2010-12-08 20:51 amp@java 閱讀(545) | 評(píng)論 (4)編輯 收藏

    有一臺(tái)WIN2003的服務(wù)器,在單位的局域網(wǎng)內(nèi),與互聯(lián)網(wǎng)是物理隔離的,最近上面運(yùn)行的一個(gè)WEB服務(wù)器經(jīng)常出錯(cuò),查看日志發(fā)現(xiàn)是因?yàn)閿?shù)據(jù)庫(kù)不能連接,因?yàn)橄到y(tǒng)的所有端口都已經(jīng)被占用完。使用netstat -abn查看發(fā)現(xiàn)svchost.exe開(kāi)啟了大量狀態(tài)為SYN_SENT的連接,目標(biāo)端口都是445,但是連接的IP各種各樣的都有,由于機(jī)器不能建立Internet連接,所以狀態(tài)都是SYN_SENT,重啟一下這些連接都沒(méi)有了,但是過(guò)一會(huì)又會(huì)迅速建立起來(lái),很快就把系統(tǒng)的所有端口都占用了。
    根據(jù)端口找出哪個(gè)服務(wù)真不容易,通過(guò)netstat -abn只能查到是svchost.exe,最多還能得到一個(gè)PID,確定是哪個(gè)svchost.exe,然后通過(guò)tasklist /svc可以查到那個(gè)svchost對(duì)應(yīng)了哪些服務(wù),但是一看,很多服務(wù)都是使用那個(gè)svchost,包括Server,Workstation等等,根本不知道是哪個(gè)產(chǎn)生的連接。
    找了半天發(fā)現(xiàn)有人和我一樣:http://www.petri.co.il/forums/showthread.php?t=36427,討論了半天最后也找到了解決方法:http://www.symantec.com/security_response/writeup.jsp?docid=2009-011316-0247-99,原來(lái)是W32.Downadup這個(gè)病毒惹的禍,下載了專(zhuān)殺工具回來(lái)查了一下,果然找到了兩個(gè)被感染的文件,一個(gè)是jpg文件,在IE的緩存里,一個(gè)是dll文件,在system32里。
    根據(jù)dll文件名在注冊(cè)表里查到了它注冊(cè)的服務(wù),原來(lái)又是之前處理過(guò)的那種,服務(wù)名隨機(jī)、服務(wù)描述為空、啟動(dòng)類(lèi)型為自動(dòng)、狀態(tài)為未啟動(dòng)、dll名隨機(jī),但是我記得這臺(tái)服務(wù)器已經(jīng)打過(guò)補(bǔ)丁,也沒(méi)有出現(xiàn)svchost錯(cuò)誤,所以就忽略了服務(wù)的檢查,沒(méi)想到這種東西還有不同的癥狀。
    這個(gè)病毒利用的是KB958644的漏洞,到微軟下載了補(bǔ)丁回來(lái),一看才發(fā)現(xiàn)原來(lái)那臺(tái)服務(wù)器以前已經(jīng)裝過(guò)這個(gè)補(bǔ)丁。補(bǔ)丁的作用也許就是只能防止再出問(wèn)題,但不能解決已有的問(wèn)題,所以那臺(tái)服務(wù)器雖然裝了補(bǔ)丁,但是可能已經(jīng)被感染了,于是就沒(méi)治好。

    posted @ 2010-06-30 11:33 amp@java 閱讀(11964) | 評(píng)論 (1)編輯 收藏

    把APE、FLAC等無(wú)損壓縮音頻文件刻錄成CD的軟件有很多,搜索一把,出現(xiàn)頻率最多的是用NERO+插件,但是現(xiàn)在的NERO體積實(shí)在龐大,我嘗試下載一個(gè)NERO 10,大小不過(guò)200多M,結(jié)果安裝的時(shí)候解壓到臨時(shí)文件夾,我的C盤(pán)1G多的空間都不夠它解壓,根本就安裝不了,為了這么一點(diǎn)事情用這么大一個(gè)軟件實(shí)在沒(méi)必要,仔細(xì)搜索一下,刻錄的軟件其實(shí)有很多,都能自動(dòng)地把APE刻錄到CD上,方法遠(yuǎn)比NERO簡(jiǎn)單。
    第一個(gè)軟件是Burrrn
    Burrrn是個(gè)專(zhuān)門(mén)干這事的軟件,它支持的文件包括ape、flac、mp3、ogg等,實(shí)際上也是通過(guò)插件來(lái)完成編碼解碼工作的,不過(guò)這些插件都是內(nèi)置在程序包里,不用再逐個(gè)下載。它的界面非常簡(jiǎn)單,使用也非常簡(jiǎn)單,基本一打開(kāi)就會(huì)使用。
    第二個(gè)軟件是ImgBurn
    這個(gè)軟件比較強(qiáng)大,不但能夠刻錄APE,還可以把光盤(pán)提取成鏡像、把文件或文件夾生成鏡像、把文件或文件夾刻錄到光盤(pán)上、把鏡像刻錄到光盤(pán)上,基本上NERO常用的功能都有了,軟件只有幾MB,十分環(huán)保。我下載這個(gè)軟件的時(shí)候只是想使用它的生成鏡像功能,因?yàn)橄螺d下來(lái)一些藍(lán)光原盤(pán)需要制作成ISO文件才能用POWERDVD播放。后來(lái)發(fā)現(xiàn)有人說(shuō)這個(gè)軟件還可以刻錄APE,不過(guò)也需要使用相關(guān)的解碼器,只是這些解碼器在安裝常用的播放器的時(shí)候一般都已經(jīng)安裝過(guò)了,例如我以前裝過(guò)終極解碼,其中包含APE解碼器,就不需要另外安裝了。
    使用的時(shí)候只需要選擇刻錄鏡像到光盤(pán)功能,選中與APE相關(guān)的cue文件,然后就可以分軌刻錄了。

    這兩個(gè)軟件的體積都很小,而且都是免費(fèi)軟件,不但環(huán)保還合法。

    第一次使用Burrrn刻錄APE的時(shí)候,用KMPlayer播放,發(fā)現(xiàn)直接播放APE的效果跟播放刻錄出來(lái)的CD效果不一樣,CD的效果動(dòng)態(tài)范圍明顯不如直接播放APE,我以為是刻錄軟件的問(wèn)題,后來(lái)使用ImgBurn刻錄,也是一樣的效果。仔細(xì)對(duì)比之后發(fā)現(xiàn)KMP播放的時(shí)候是使用不同的濾鏡,可能是這個(gè)原因?qū)е滦Ч煌遣シ臕PE和播放CD又不可能使用相同的濾鏡,所以到底是什么原因也很難說(shuō)得清楚,不過(guò)CD機(jī)上不認(rèn)APE,也只能這樣了。


    posted @ 2010-06-22 15:30 amp@java 閱讀(584) | 評(píng)論 (0)編輯 收藏

    1、服務(wù)命名。Oracle的服務(wù)命名就跟計(jì)算機(jī)的名稱(chēng)一樣。一般來(lái)說(shuō),在局域網(wǎng)里面,計(jì)算機(jī)名稱(chēng)是與IP一一對(duì)應(yīng)的,通信的時(shí)候需要使用IP,所以就有了DNS,把計(jì)算機(jī)名翻譯成IP。同樣的道理,在Oracle體系里,服務(wù)命名對(duì)應(yīng)計(jì)算機(jī)名,服務(wù)名(SID)+IP+端口+協(xié)議(TCP/IP)就對(duì)應(yīng)了計(jì)算機(jī)的IP,Oracle體系里的DNS其實(shí)就是一個(gè)配置文件,把服務(wù)命名翻譯成可以用于通信的服務(wù)名(SID)+IP+端口+協(xié)議(TCP/IP)。有趣的是,與計(jì)算機(jī)里的ping命令一樣,Oracle里面也有個(gè)TNSPing命令,通過(guò)“TNSPing 服務(wù)命名”,就會(huì)得到像ping命令相似的結(jié)果,驗(yàn)證該命名對(duì)應(yīng)的數(shù)據(jù)庫(kù)是否有效。

    2、主機(jī)身份驗(yàn)證。Oracle的一些維護(hù)工作往往需要輸入主機(jī)身份驗(yàn)證信息,但是默認(rèn)情況下,即使輸入了正確的用戶(hù)名和密碼,系統(tǒng)也會(huì)提示“用戶(hù)口令錯(cuò)誤”,讓人十分困惑。其實(shí)真實(shí)的原因是,你輸入的用戶(hù)必須在“作為批處理作業(yè)登錄”里面,否則就會(huì)出現(xiàn)上述錯(cuò)誤。操作方法如下:運(yùn)行-gpedit.msc-計(jì)算機(jī)配置-Windows設(shè)置-安全設(shè)置-本地策略-用戶(hù)權(quán)利指派-作為批處理作業(yè)登錄-添加用戶(hù)或組...-加入要登錄的用戶(hù)。
    執(zhí)行數(shù)據(jù)庫(kù)遷移操作的時(shí)候,可能需要在源數(shù)據(jù)庫(kù)主機(jī)和目標(biāo)數(shù)據(jù)庫(kù)主機(jī)都進(jìn)行上述操作才能成功。

    更多問(wèn)題待續(xù)
    posted @ 2009-11-12 10:23 amp@java 閱讀(280) | 評(píng)論 (0)編輯 收藏

    9月10號(hào),CHDBits開(kāi)放了注冊(cè)權(quán)限,趕緊注冊(cè)了一個(gè)帳戶(hù),這是我第一次登錄PT站。每個(gè)文件都有幾個(gè)甚至幾十個(gè)種子在等待下載者,真是“僧多粥少”。下載速度果然很猛,下了幾個(gè)文件,基本上可以達(dá)到ADSL的上限,甚至遇到了前所未有的極速,不過(guò)持續(xù)時(shí)間較短,但是平均速度都接近上限。
    然而,ADSL小水管終究不是玩PT的料,嚴(yán)格的分享率要求和ADSL龜速的上傳帶寬使得我兩天之后就變成了冰人,如果20天之內(nèi)再不提高分享率,我的帳戶(hù)將會(huì)被封禁。仔細(xì)考慮了一下,我還是“過(guò)把癮就死”算了,因?yàn)橐晕疫@8:1的上傳和下載帶寬,要長(zhǎng)期達(dá)到要求基本上是不可能的事情,如果要我的分享率達(dá)到1:1,那我4M的下載帶寬就等于縮水成和上傳帶寬一樣,只有512K了,我裝這4M的寬帶還有什么意義?
    其實(shí)在PT站外下載,速度也是不錯(cuò)的,無(wú)論是emule還是BT都能達(dá)到上限的80%以上,當(dāng)然,是在種子剛剛放出的一段時(shí)間,只要熱度一過(guò),速度馬上下降,這是與PT沒(méi)法比的。
    還是等到哪一天光纖到戶(hù)再玩PT吧,現(xiàn)在的任務(wù)就是趁著20天沒(méi)過(guò),趕緊“過(guò)癮”,嘿嘿!
    posted @ 2009-09-14 19:44 amp@java 閱讀(294) | 評(píng)論 (2)編輯 收藏

    VISTA和WIN7都有一種OEM激活法,該激活方式需要以下三個(gè)條件:
    1、BIOS中有相應(yīng)廠商的SLIC,VISTA要求SLIC 2.0,WIN7則要求SLIC 2.1。一般來(lái)說(shuō),品牌機(jī)的BIOS里面本來(lái)都帶有SLIC,不過(guò)有的沒(méi)打開(kāi)(例如DELL的OPTIPLEX系列),需要用一些小工具打開(kāi)(例如Asset);有的版本是2.0的,只能用來(lái)激活VISTA,如果要激活WIN7,需要更新SLIC,但更新官方的BIOS并不會(huì)更新SLIC,因此還需要找到專(zhuān)門(mén)的修改過(guò)的BIOS文件來(lái)更新。
    2、安裝的VISTA或者WIN7導(dǎo)入了相應(yīng)的OEM廠商的證書(shū),如果安裝的系統(tǒng)是OEM版的,安裝完之后證書(shū)就在里面了;如果安裝的是普通版本的,還需要手動(dòng)導(dǎo)入,命令為:
    slmgr.vbs -ilc <證書(shū)路徑>
    一般每個(gè)廠商都只有一個(gè)證書(shū),而且VISTA和WIN7的證書(shū)是相同的,也就是說(shuō)相同的證書(shū)可同時(shí)用于VISTA或者WIN7。
    3、所安裝的VISTA或WIN7的key,與證書(shū)不同,key是每個(gè)版本的Windows一個(gè),HomeBasic,HomePremium,Business,Ultimate等版本分別有各自的key,VISTA和WIN7的key也是不同的。導(dǎo)入key的方式是運(yùn)行以下命令:
    slmgr.vbs -ipk <key>
    如果安裝的時(shí)候輸入了相應(yīng)的key就不用這一步了。

    同時(shí)具備了上述條件的VISTA和WIN7就被激活了,這些條件不需要按順序來(lái)準(zhǔn)備,只要具備即可,也就是說(shuō)系統(tǒng)安裝后再刷BIOS,或者系統(tǒng)安裝前刷BIOS都是可以的。
     關(guān)于BIOS的信息,可瀏覽: 
    http://www.bios.net.cn

    關(guān)于Windows的信息,可瀏覽:
    http://www.pcbeta.com
    posted @ 2009-08-17 21:22 amp@java 閱讀(356) | 評(píng)論 (0)編輯 收藏

    jQuery UI里面只有一個(gè)DatePicker,只能選擇日期,不能選擇時(shí)間,有人做了一個(gè)可以選擇時(shí)間的DateTimePicker,在這里(http://razum.si/jQuery-calendar/TimeCalendar.html)可以看到,把jquery.js,jquery-calendar.js,jquery-calendar.css下回來(lái)之后就可以用了。
    但是有幾個(gè)Bug需要自己修改:
    1、當(dāng)輸入框里面的時(shí)間是0點(diǎn)時(shí),控件顯示不完整,這是因?yàn)橛袀€(gè)函數(shù)有bug,如下所示:

    ???? /* ?Ensure?numbers?are?not?treated?as?octal.? */
    ????trimNumber:?
    function (value)?{
    ????????
    if ?(value? == ?'')
    ????????????
    return ?'';
    ????????
    while ?(value.charAt( 0 )? == ?' 0 '? )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}
    ????????
    return ?value;
    ????},

    ???????? while ?(value.charAt( 0 )? == ?' 0 '? )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}

    這一句,如果是0點(diǎn)的話,最終會(huì)出錯(cuò),因?yàn)樗拈L(zhǎng)度最后是1,不能執(zhí)行substring(1),改成下面就好了:

    ???? /* ?Ensure?numbers?are?not?treated?as?octal.? */
    ????trimNumber:?
    function (value)?{
    ????????
    if ?(value? == ?'')
    ????????????
    return ?'';
    ????????
    while ?(value.charAt( 0 )? == ?' 0 '? && ?value.length >1 )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}
    ????????
    return ?value;
    ????},

    2、作者是在jQuery 1.1.2版本下實(shí)現(xiàn)的,現(xiàn)在最新版本是1.3.2,這個(gè)控件在1.3.2下會(huì)出現(xiàn)異常,不能選擇日期,這是因?yàn)橛袔讉€(gè)選擇器有問(wèn)題:
    ?1?????????$('.calendar_daysRow?td[a]').hover(?//?highlight?current?day
    ?2?????????????function()?{
    ?3?????????????????$(this).addClass('calendar_daysCellOver');
    ?4?????????????},?function()?{
    ?5?????????????????$(this).removeClass('calendar_daysCellOver');
    ?6?????????});
    ?7?????????$('.calendar_daysRow?td[a]').click(function()?{?//?select?day
    ?8?????????????popUpCal.selectedDay?=?$("a",this).html();
    ?9?????????????popUpCal.selectDate();
    10?????????});
    上面的$('.calendar_daysRow?td[a]')在jQuery 1.3.2中不能使用,$("a",this)也是有問(wèn)題的,同時(shí),在FireFox中,<a>的不能設(shè)置背景顏色,所以hover函數(shù)不起作用,把它設(shè)在<td>也能達(dá)到相同的效果,改成以下代碼即可:
    ?1?????????//$('.calendar_daysRow?td?a').hover(?//?highlight?current?day
    ?2?????????$('.calendar_daysRow?td').hover(?//?highlight?current?day
    ?3?????????????function()?{
    ?4?????????????????$(this).addClass('calendar_daysCellOver');
    ?5?????????????},?function()?{
    ?6?????????????????$(this).removeClass('calendar_daysCellOver');
    ?7?????????});
    ?8?????????//$('.calendar_daysRow?td[a]').click(function()?{?//?select?day
    ?9?????????$('.calendar_daysRow?td?a').click(function()?{?//?select?day
    10?????????????//alert("click");
    11?????????????//popUpCal.selectedDay?=?$("a",this).html();
    12?????????????popUpCal.selectedDay?=?$(this).html();
    13?????????????popUpCal.selectDate();
    14?????????});

    經(jīng)過(guò)修改之后在IE7和FireFox3都能在jQuery 1.3.2環(huán)境下正常運(yùn)行。
    posted @ 2009-05-22 19:37 amp@java 閱讀(41555) | 評(píng)論 (19)編輯 收藏

    初次使用jQuery,發(fā)現(xiàn)真是個(gè)好東西,把很多東西都簡(jiǎn)化了,循環(huán)基本上都去掉了,可以說(shuō)是開(kāi)創(chuàng)了JS的一種新模式,雖然開(kāi)始覺(jué)得有點(diǎn)不習(xí)慣,但是很容易學(xué)習(xí)也很容易看懂。一個(gè)神奇的$原來(lái)有那么多的功能,很強(qiáng)大,呵呵。
    最讓人欣慰的是它屏蔽了所有瀏覽器的差別,可以在各種瀏覽器上用相同的代碼實(shí)現(xiàn)相同的效果。

    posted @ 2009-05-21 18:42 amp@java 閱讀(263) | 評(píng)論 (0)編輯 收藏

    二維條形碼比普通的條形碼能保存更多的信息,已經(jīng)應(yīng)用到很多領(lǐng)域里面。例如手機(jī)電影票,就是一個(gè)嵌在彩信里面的二維碼圖像。南航也推出了網(wǎng)上辦理登機(jī)牌業(yè)務(wù),辦理完成之后往手機(jī)發(fā)送一條包含二維碼的彩信,到了機(jī)場(chǎng)就可以通過(guò)自助設(shè)備掃描二維碼,打印登機(jī)牌。
    然而,專(zhuān)業(yè)的二維碼掃描設(shè)備價(jià)格十分昂貴,最便宜的都在1000元以上,到淘寶上搜搜就知道了。借助Java和一個(gè)開(kāi)源的庫(kù),我們卻可以通過(guò)普通的網(wǎng)絡(luò)攝像頭實(shí)現(xiàn)相同的效果,成本只需要幾十塊。
    Open Source QR Code Library是一個(gè)開(kāi)源的QR Code(二維條形碼的一種)生成和讀取的庫(kù),官方網(wǎng)站為:http://qrcode.sourceforge.jp/,里面包含了生成和讀取QR Code的所有代碼,其中有個(gè)jmfexample就能實(shí)現(xiàn)通過(guò)攝像頭讀取QR Code,經(jīng)過(guò)本人嘗試,幾十塊的普通攝像頭效果已經(jīng)不錯(cuò)了,一次讀取幾百字節(jié)都沒(méi)問(wèn)題。
    使用這個(gè)庫(kù)的步驟如下:
    1、到其官方網(wǎng)站下載回來(lái);
    2、到sun的網(wǎng)站下載JMF包并安裝;
    3、插上攝像頭,打開(kāi)我的電腦,查看是否出現(xiàn)“USB視頻設(shè)備”,然后打開(kāi),看攝像頭工作是否正常
    4、運(yùn)行JMF里面的JMF Registry程序,點(diǎn)擊“Detect Capture Devices”,查找視頻設(shè)備,查找到之后會(huì)在左邊的列表里出現(xiàn)“vfw:Microsoft WDM Image Capture (Win32):0”類(lèi)似的設(shè)備,點(diǎn)擊就會(huì)在右邊出現(xiàn)其詳細(xì)信息,我的攝像頭是這樣的:
    Name = vfw:Microsoft WDM Image Capture (Win32):0

    Locator = vfw://0

    Output Formats---->

    0. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 3

    1. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=160,height=120] MaxDataLength = 38400 DataType = class [B yuvType = 32 StrideY = 320 StrideUV = 320 OffsetY = 0 OffsetU = 1 OffsetV = 3

    2. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=176,height=144] MaxDataLength = 50688 DataType = class [B yuvType = 32 StrideY = 352 StrideUV = 352 OffsetY = 0 OffsetU = 1 OffsetV = 3

    3. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=320,height=240] MaxDataLength = 153600 DataType = class [B yuvType = 32 StrideY = 640 StrideUV = 640 OffsetY = 0 OffsetU = 1 OffsetV = 3

    4. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=352,height=288] MaxDataLength = 202752 DataType = class [B yuvType = 32 StrideY = 704 StrideUV = 704 OffsetY = 0 OffsetU = 1 OffsetV = 3

    注意,其中Output Formats都是javax.media.format.YUVFormat,而QR Code Library里默認(rèn)的設(shè)備不是這種格式的,所以需要對(duì)源碼作一定的修改。

    5、用Eclipse打開(kāi)QR Code Library的源碼,作出一些適當(dāng)?shù)男薷模?br />如果攝像頭是上面所說(shuō)的只支持YUV格式,則需要修改jp.sourceforge.qrcode.example.jmf.camDataSource.java,把setMainSource函數(shù)里的
    VideoFormat vidformat = new VideoFormat(VideoFormat.RGB);
    修改為
    VideoFormat vidformat = new VideoFormat(VideoFormat.YUV);
    否則永遠(yuǎn)也找不到攝像頭。

    6、把JMF包里的jmf.jar放到Classpath里
    7、執(zhí)行jp.sourceforge.qrcode.example.jmf.jmfexample,搞定

    當(dāng)然,由于源碼開(kāi)放的,只要符合許可,你想怎么改都行,可以把它嵌入到某個(gè)應(yīng)用程序里面,這個(gè)程序就具有了掃描QR Code的功能了。

    posted @ 2009-04-02 16:22 amp@java 閱讀(5936) | 評(píng)論 (13)編輯 收藏

    今天早上回到單位發(fā)現(xiàn)好幾部服務(wù)器都出現(xiàn)了與svchost.exe有關(guān)的錯(cuò)誤,有一臺(tái)svchost.exe進(jìn)程占用CPU達(dá)到100%,慢如蝸牛。普通PC機(jī)上則出現(xiàn)網(wǎng)絡(luò)時(shí)斷時(shí)續(xù),重啟后能打開(kāi)網(wǎng)頁(yè),但很快就所有網(wǎng)頁(yè)打不開(kāi),某些網(wǎng)絡(luò)程序運(yùn)行時(shí)則出現(xiàn)緩沖區(qū)已滿等錯(cuò)誤。更新病毒庫(kù)查毒后發(fā)現(xiàn)整個(gè)局域網(wǎng)的所有電腦都出現(xiàn)Hack.Exploit.Win32.MS08-067.k病毒,殺毒軟件顯示svchost.exe里的病毒已清除,但是重啟又出現(xiàn)。
    搜索得知這是MS08-067漏洞導(dǎo)致,于是下載補(bǔ)丁,打上,但是病毒并沒(méi)有清除。無(wú)奈只能求助高人,在高人指點(diǎn)下找到了病毒位置并清之,過(guò)程如下:
    1、運(yùn)行,輸入services.msc,打開(kāi)服務(wù)管理器,按照“描述”排序,在“描述”欄為空的那幾項(xiàng)服務(wù)中查找一個(gè)名字很奇怪、由幾個(gè)隨機(jī)字符組成、沒(méi)有任何意義的服務(wù),它的狀態(tài)一般是停止,但是啟動(dòng)模式是自動(dòng),這里要把它改成已禁用;
    2、重啟電腦;
    3、運(yùn)行,輸入regedit,打開(kāi)注冊(cè)表編輯器,輸入那個(gè)奇怪服務(wù)的名字進(jìn)行查找,找到以那個(gè)名字命名的鍵值,在其下面有個(gè)名為Parameters的子鍵,該子鍵內(nèi)有個(gè)ServiceDll的字符串值,就是病毒文件所在,找到那個(gè)病毒文件并刪之;
    4、到微軟網(wǎng)站下載MS08-067補(bǔ)丁,打上,搞定!

    這是我第一次碰到這種迅速感染整個(gè)局域網(wǎng)的病毒,似乎跟當(dāng)年的沖擊波有得比,搞起來(lái)煩得要命,幾十臺(tái)機(jī)啊……
    posted @ 2009-01-08 23:05 amp@java 閱讀(5098) | 評(píng)論 (2)編輯 收藏

    現(xiàn)在的手機(jī)大多具有藍(lán)牙功能,手機(jī)上的JavaME程序也能訪問(wèn)藍(lán)牙端口,藍(lán)牙的協(xié)議有多種,但最簡(jiǎn)單的可能就是虛擬串口(rfcomm)協(xié)議了,在該協(xié)議中,藍(lán)牙端口被虛擬成一個(gè)串口,只要獲取其InputStream和OutputStream后,就可以進(jìn)行讀寫(xiě)操作了,與socket差不多。 待續(xù)…
    posted @ 2008-11-27 19:16 amp@java 閱讀(871) | 評(píng)論 (0)編輯 收藏

    為了充分利用晚上的帶寬,我搞了一部專(zhuān)門(mén)的破機(jī)用于BT/EMULE下載,上班時(shí)間為了不影響大家上網(wǎng),必須停止下載任務(wù)。有的下載工具本身帶有計(jì)劃任務(wù)功能,但是有些只能控制速度,不能控制連接,例如eMule,雖然可以停止下載,但是連接還是很多的,脆弱的ADSL路由/Modem經(jīng)不起大量的連接,很容易就死翹翹了。這種情況下,最痛快的解決辦法是拔線,但是每天插拔也不是辦法,軟一點(diǎn)的辦法是禁用網(wǎng)卡,但是每次手動(dòng)操作也不是辦法。更直接的辦法就是計(jì)劃任務(wù)自動(dòng)啟用/禁用網(wǎng)卡了。要實(shí)現(xiàn)這種目的必須要有能夠自動(dòng)運(yùn)行的工具,devcon就是一個(gè)命令行工具,能夠在命令行中實(shí)現(xiàn)“設(shè)備管理器”的功能,我這里只要“啟用/禁用”功能即可。
    devcon的下載地址:
    http://support.microsoft.com/kb/311272/zh-cn
    微軟出品,權(quán)威產(chǎn)品。

    使用的時(shí)候還是有點(diǎn)小問(wèn)題,搜索了一下找不到答案,只有自己解決了:
    1、禁用設(shè)備的命令是:
    devcon disable 設(shè)備ID
    這個(gè)設(shè)備ID怎么得到呢?通過(guò)設(shè)備管理器,在設(shè)備上點(diǎn)擊“屬性”,在“詳細(xì)信息”標(biāo)簽里面有個(gè)下拉列表,選擇“設(shè)備范例Id”,下面顯示出來(lái)的就是設(shè)備ID,
    怎么把這個(gè)ID復(fù)制出來(lái)呢?右鍵是沒(méi)辦法的,但是直接CTRL+C就OK了。
    2、設(shè)備ID不能直接輸入,否則會(huì)把ID開(kāi)頭相同的一大堆設(shè)備都操作一遍,最后還會(huì)出幾個(gè)錯(cuò)誤提示;加上雙引號(hào)也不行,會(huì)提示沒(méi)有設(shè)備被禁用/啟用;必須這樣寫(xiě):@"設(shè)備ID",所以最后的命令格式是:
    devcon disable @"設(shè)備ID"
    不知道是什么道理。

    在計(jì)劃任務(wù)里面添加兩個(gè)任務(wù):“啟用網(wǎng)卡”,“禁用網(wǎng)卡”,分別用devcon enable,devcon disable命令即可,例如早上8點(diǎn)半禁用,晚上23:30啟用(有部分好筒子晚上加班)。這樣一來(lái),就可以24小時(shí)開(kāi)著那幾個(gè)下載程序也不會(huì)有影響了,在網(wǎng)卡禁用的時(shí)候,無(wú)論它們?cè)趺磭L試連接,都跳不出如來(lái)佛的掌心。

    posted @ 2008-08-28 17:19 amp@java 閱讀(3283) | 評(píng)論 (3)編輯 收藏

    說(shuō)來(lái)慚愧,雖然工作學(xué)習(xí)都離不開(kāi)計(jì)算機(jī),但直到兩個(gè)星期以前,我還沒(méi)有為自己買(mǎi)過(guò)一臺(tái)新電腦,倒是給人家裝了快10臺(tái)。近段時(shí)間終于下定決心買(mǎi)臺(tái)電腦了。我不玩游戲,買(mǎi)電腦只是為了上網(wǎng),看片,寫(xiě)點(diǎn)小程序。現(xiàn)在流行高清電影,上了一下相關(guān)論壇,發(fā)現(xiàn)要流暢“軟解”H264編碼的1080P電影,至少需要4核的CPU,Intel的Q6600盒裝1500左右,AMD 羿龍9550 1100左右,前者的性能好于后者,但是Intel的集成主板又貴又爛,AMD 的780G芯片組是目前最強(qiáng)的整合芯片組,價(jià)格便宜量又足,于是就把架構(gòu)定在AMD上。技嘉的GA-MA78GM-S2H 是論壇上討論最多的主板,應(yīng)該也是用的人最多的780G主板之一,憑借技嘉優(yōu)秀的做工,充足的用料,豐富的接口,贏得了廣泛的好評(píng),但是這個(gè)是小板,由于面積的局限,南北橋芯片發(fā)熱比較厲害。后來(lái)技嘉推出了標(biāo)準(zhǔn)ATX板型的GA-MA78G-DS3H ,采用了全固態(tài)電容(小板是供電部分全固態(tài)),減少了一個(gè)ESATA接口,增加了一個(gè)1394接口,增加了三條PCI-E插槽,散熱效果應(yīng)該比小板好,于是就定下了這塊主板。由于高清電影動(dòng)輒10G以上,所以買(mǎi)了個(gè)希捷500G 7200.11硬盤(pán),以后降價(jià)的話再加一個(gè)做RAID 0就爽了。內(nèi)存選用kingston 1G * 2 DDR2-800組成雙通道。光驅(qū)是明基DW2000 DVD刻錄機(jī)。這些都很快定下來(lái)了,倒是機(jī)箱和電源費(fèi)了不少腦筋。看了不少評(píng)論和測(cè)評(píng),最后才定下了航嘉的“時(shí)光之門(mén)”機(jī)箱,看中的就是它的用料和4個(gè)前置USB+一個(gè)1394口。電源要選主動(dòng)PFC,效率更高,同時(shí)也要額定400W以上,因?yàn)槟莻€(gè)CPU的TDP就有95W,挑了半天,定在TT的KK500A,額定功率400W,主動(dòng)PFC,14CM大風(fēng)扇。顯示器22寸液晶就可以了,我對(duì)它的要求不高,因?yàn)榭雌脑捯彩峭ㄟ^(guò)HDMI接到液晶電視上看,初步?jīng)Q定三星2243BW。
    這一切準(zhǔn)備好之后,找了個(gè)時(shí)間殺到電腦城。報(bào)價(jià)如下:
    CPU     Phenom X4 9550 盒裝 1120
    主板 技嘉GA-MA78G-DS3H  680
    內(nèi)存 Kingston DDR2-800 1G*2 140*2=280
    硬盤(pán) 希捷7200.11 500GB 585
    光驅(qū) BenQ DW2000 DVD刻錄機(jī) 225
    機(jī)箱 航嘉時(shí)光之門(mén)H301 265
    電源 TT KK500P (KK500A的升級(jí)版) 470
    顯示器 三星 2243BW 1850
    鍵盤(pán)鼠標(biāo) 雜牌套裝 30
    合計(jì) 5505

    挑好之后我讓JS備貨,然后就回去了。過(guò)了沒(méi)多久,JS打電話來(lái)說(shuō)AMD的那個(gè)CPU沒(méi)貨,問(wèn)我要不要9750,我說(shuō)算了,等有貨再裝吧,那個(gè)CPU的TDP 125W,太恐怖。結(jié)果過(guò)了兩天,還是沒(méi)貨,我打電話問(wèn)了本市的其他電腦店,也是沒(méi)貨,說(shuō)是奧運(yùn)影響了物流(不得不說(shuō)奧運(yùn)真是勞民傷財(cái),個(gè)人觀點(diǎn),不要上綱上線)。JS出了個(gè)主意說(shuō)讓我先用雙核的4800+,有貨的時(shí)候再換成9550。開(kāi)始的時(shí)候我不同意,考慮到淘寶自己買(mǎi),問(wèn)了一下真的有賣(mài)的,還比JS那里便宜20塊,但是又怕出現(xiàn)問(wèn)題不知道找誰(shuí),雖然盒裝全國(guó)聯(lián)保,但是我這個(gè)小地方好像沒(méi)有AMD的代理。最后還是同意了JS的辦法,再奔電腦城,把裝了4800+的主機(jī)扛了回來(lái)。顯示器我問(wèn)過(guò)三星的代理,只要1790,JS說(shuō)他賣(mài)不了這個(gè)價(jià),于是就不要顯示器,鍵盤(pán)鼠標(biāo)看了一下,也很爛,不要。回來(lái)打開(kāi)電腦,我靠,居然一點(diǎn)聲音都沒(méi)有,真的,從來(lái)沒(méi)見(jiàn)過(guò)這么安靜的電腦,如果不是燈亮著,跟沒(méi)開(kāi)一個(gè)樣。可能歸功于電源那14cm的風(fēng)扇,只要很低的轉(zhuǎn)速就可以產(chǎn)生大風(fēng)量。上淘寶買(mǎi)了根3米長(zhǎng)的HDMI線,接到家里的32寸液晶上,很郁悶地發(fā)現(xiàn)不能點(diǎn)對(duì)點(diǎn),那個(gè)電視的物理分辨率是1366*768,但卻不支持這個(gè)輸入分辨率。沒(méi)辦法,只好用1280*720輸入,看文字比較模糊,但也沒(méi)多大影響。看電影那叫一個(gè)爽,比電腦上爽多了。
    前天去電腦城買(mǎi)了一套雙飛燕的防水鼠標(biāo)鍵盤(pán)套裝KB-827D,65塊。昨天和一個(gè)同事一起想去買(mǎi)三星的那款顯示器,無(wú)意中卻看到了一款A(yù)OC的2280V,參數(shù)和三星2243BW基本一樣,但是價(jià)格便宜不少,只要1540,還帶DVI線,3年質(zhì)保,比三星的D-SUB線+1年質(zhì)保要好。于是就要了一臺(tái),店家包無(wú)點(diǎn),開(kāi)箱檢查了一下,兩臺(tái)都是完美屏,拿回來(lái)了。
    這個(gè)過(guò)程中,最郁悶的事情是弄那幾個(gè)顯示接口了。780G的主板一般都帶有D-SUB、DVI-D、HDMI三種接口,但是DVI和HDMI接口不能同時(shí)使用。技嘉的這塊主板就是這樣,而且還是自動(dòng)選擇HDMI,也就是插上DVI和HDMI之后只有HDMI有東西。AOC的那兩個(gè)接口也是自動(dòng)選擇,也就是兩個(gè)接口都插上的話,就會(huì)自動(dòng)選擇DVI(本來(lái)可以手動(dòng)選擇的,但是如果兩個(gè)都插上的話好像手動(dòng)選擇無(wú)效)。
    首先碰到的問(wèn)題是聲音。按照主板的說(shuō)明書(shū),如果需要通過(guò)HDMI口輸出聲音的話,必須在控制面板->聲音和音頻設(shè)備->音頻里面在聲音播放默認(rèn)設(shè)備下選擇Realtek HDA HDMI Out。但是我把電腦搬回單位折騰的時(shí)候,發(fā)現(xiàn)這里并沒(méi)有出現(xiàn)Realtek HDA HDMI Out這個(gè)選項(xiàng),只有Realtek HD Audio output!在設(shè)備管理器里卻能發(fā)現(xiàn)ATI HDMI Audio這個(gè)設(shè)備。搜索了半天,好像有人遇到過(guò)這個(gè)問(wèn)題,但是沒(méi)有答案;有人說(shuō)在BIOS里面開(kāi)啟,但我發(fā)現(xiàn)默認(rèn)已經(jīng)開(kāi)啟了;打電話給技嘉客服,那個(gè)人叫我先接上電視試試。那時(shí)候還沒(méi)有買(mǎi)HDMI線,試不了,于是就不管它了。結(jié)果HDMI線到了之后,一接上電視,馬上就出聲了,暈啊,原來(lái)必須插上HDMI線之后才能選擇那個(gè)Realtek HDA HDMI Out!!!!
    昨天把顯示器買(mǎi)回來(lái)之后也碰到問(wèn)題了。我把DVI口和D-SUB口和HDMI口都接上了,啟動(dòng)電腦,顯示器自動(dòng)選擇DVI輸入,自檢界面->Windows滾動(dòng)條都沒(méi)問(wèn)題,但是滾動(dòng)條過(guò)去之后,顯示器提示沒(méi)信號(hào),黑屏了,怎么按都沒(méi)反應(yīng),選擇信源也不行。只能關(guān)機(jī)重啟,然后按F8選擇VGA模式,進(jìn)去之后分辨率是640*480,沒(méi)問(wèn)題,但是只要一調(diào)整分辨率,無(wú)論是調(diào)成800*600還是1680*1050,都一樣的沒(méi)信號(hào),黑屏。把D-SUB線和DVI線分別拔下,還是不行。想到ATI控制中心里面看看,結(jié)果偏偏在這個(gè)時(shí)候ATI控制中心啟動(dòng)不了!!重裝驅(qū)動(dòng),還是不行。下載最新的8.7的催化劑驅(qū)動(dòng),一裝完重啟就藍(lán)屏。只要又裝回8.6版。搞了三四個(gè)小時(shí),弄到最后,把HDMI線拔了下來(lái),只接一個(gè)DVI到顯示器,居然一切正常了,啟動(dòng)成功,分辨率1680*1050,完美。仔細(xì)一想,才明白原來(lái)這塊主板只支持DVI和HDMI其中之一輸出,而且接上HDMI后默認(rèn)就輸出HDMI了,雖然我那電視一直沒(méi)開(kāi),但是線插上之后就不再輸出DVI了。把DVI拔了之后,由于之前只有電視作為顯示器,沒(méi)有配置雙顯示器輸出,所以D-SUB也不會(huì)有信號(hào),所以無(wú)論拔DVI還是拔D-SUB都沒(méi)信號(hào),只有拔HDMI才行。這時(shí)候我又嘗試安裝中文版的8.6 ATI控制中心,裝完之后還是啟動(dòng)不了,嘗試一下Restart Runtime,我靠,居然就可以啟動(dòng)了!!神奇!!!進(jìn)去把顯示器作為主顯示,電視作為擴(kuò)展。重啟之后顯示器和電視機(jī)都能顯示了,而且顯示器是1680*1050,電視是1280*720,調(diào)整了一下電視的過(guò)掃描,使它滿屏,然后用KMPlayer放電影,把窗口拖到電視那邊,全屏,好了,可以一邊在書(shū)房上網(wǎng)一邊在客廳放電影了(我在書(shū)房和客廳之間的墻上打了個(gè)洞)!!有點(diǎn)遺憾的是,顯示器只能用D-SUB輸入,浪費(fèi)了那根DVI線。不過(guò)這個(gè)可以通過(guò)獨(dú)立顯卡來(lái)解決,以后再說(shuō)吧。
    780G主板的確厲害,集成的顯卡可以輕松硬解1080P的視頻,CPU占用不到10%,但是有時(shí)候會(huì)出現(xiàn)綠格子,還有一些奇怪的現(xiàn)象。所以可能的話我還是盡量使用軟解。不過(guò)到目前為止,4核CPU還沒(méi)到貨,這個(gè)4800+軟解VC1有時(shí)候都會(huì)卡,更別說(shuō)H264了。而且AMD那個(gè)原裝風(fēng)扇實(shí)在太爛了,看片的時(shí)候60多度,甚至死機(jī),必須把蓋子打開(kāi),拿個(gè)臺(tái)扇往里吹才能把一部片子看完。后來(lái)花10塊買(mǎi)了個(gè)12cm的機(jī)箱風(fēng)扇,裝上之后似乎也沒(méi)什么效果。看來(lái)只能換CPU散熱器了,初步?jīng)Q定買(mǎi)個(gè)九州風(fēng)神的β400+,100左右,4根熱管的,對(duì)付那個(gè)9550應(yīng)該可以吧。不過(guò)要等CPU到了再買(mǎi)。突然發(fā)現(xiàn),DIY就是個(gè)燒錢(qián)的過(guò)程,我多年的積蓄已經(jīng)花得差不多了……
    到目前投入的錢(qián):
    主機(jī)3625+顯示器1540+機(jī)箱風(fēng)扇10+HDMI線190+鼠標(biāo)鍵盤(pán)65=5430
    預(yù)計(jì)還要投入的散熱器,突破5500了!!
    這就是我的第一臺(tái)自用新電腦。

    2008年9月6日更新:
    截至目前,已在淘寶上購(gòu)入如下附件:
    1、九州風(fēng)神β400+散熱器一個(gè),連郵費(fèi)102塊。買(mǎi)回來(lái)裝上才發(fā)現(xiàn)噪音太大了,不得已只好DIY了一下,把風(fēng)扇拆掉,裝上原裝散熱器的風(fēng)扇。
    2、為了在客廳控制電腦,買(mǎi)了個(gè)無(wú)線鼠標(biāo),太科的,可能是山寨貨,連郵費(fèi)82,剛開(kāi)始的時(shí)候直接在客廳就可以穿墻控制書(shū)房的電腦了,不過(guò)第二次就不行了,可能電力不足吧,現(xiàn)在只能把鼠標(biāo)拿到墻邊才能有,已經(jīng)買(mǎi)了一條5m的USB延長(zhǎng)線,明天送貨。
    posted @ 2008-07-27 21:35 amp@java 閱讀(481) | 評(píng)論 (2)編輯 收藏

         摘要: Nokia MMS Library是一個(gè)開(kāi)放源代碼的Java MMS開(kāi)發(fā)包,里面包含了源碼、文檔、示例程序等,很容易就能學(xué)會(huì)。下面是用這個(gè)包發(fā)送彩信的方法: 1、電腦通過(guò)GPRS/EDGE MODEM或手機(jī)連接移動(dòng)夢(mèng)網(wǎng),注意,必須是移動(dòng)夢(mèng)網(wǎng)(CMWAP),不是互聯(lián)網(wǎng)(CMNET),如果手動(dòng)撥號(hào),一般是撥*99***1#或*99***2#,撥通之后打開(kāi)命令行窗口,telnet 10.0.0.172...  閱讀全文
    posted @ 2008-06-17 14:35 amp@java 閱讀(3466) | 評(píng)論 (11)編輯 收藏

    這幾天要在單位部署一個(gè)軟件包,是msi形式的,據(jù)說(shuō)可以通過(guò)“域推送”的形式安裝,搜索了一下,發(fā)現(xiàn)需要在 組策略->軟件設(shè)置->軟件安裝 里面添加放在共享目錄里的軟件包。但是我試過(guò)無(wú)論在“計(jì)算機(jī)配置”里面還是在“用戶(hù)配置”里面添加那個(gè)軟件包,無(wú)論是“發(fā)布”還是“指派”,都沒(méi)辦法自動(dòng)安裝,最多只是在“添加刪除程序”里面的“添加新程序”出現(xiàn)那個(gè)軟件包,還需要手動(dòng)安裝。
    域控制器上按照部門(mén)劃分了多個(gè)組織單位(OU),并把用戶(hù)分配到各自的組織單位中,組策略就是在這些組織單位上面應(yīng)用的。
    昨天晚上看了一下“Windows2000資源大全”,里面有講到這種軟件安裝方法。原來(lái)是要把計(jì)算機(jī)也劃分到組織單位中,然后在那個(gè)組織單位的組策略的“計(jì)算機(jī)配置”里面設(shè)置那個(gè)軟件包,當(dāng)計(jì)算機(jī)啟動(dòng)后,進(jìn)入“應(yīng)用計(jì)算機(jī)設(shè)置”階段,還沒(méi)出現(xiàn)登錄界面時(shí),就會(huì)自動(dòng)安裝。之前對(duì)組策略的理解有問(wèn)題,以為組策略只應(yīng)用于用戶(hù),實(shí)際上是“用戶(hù)配置”應(yīng)用于用戶(hù),“計(jì)算機(jī)配置”應(yīng)用于計(jì)算機(jī),要對(duì)讓每臺(tái)計(jì)算機(jī)自動(dòng)安裝,而不是在用戶(hù)登錄之后安裝,就必須在“計(jì)算機(jī)配置”里面設(shè)置,要把這個(gè)設(shè)置應(yīng)用于所有計(jì)算機(jī),就要把那些計(jì)算機(jī)劃分到某個(gè)組織單位,然后對(duì)這個(gè)組織單位應(yīng)用組策略。

    之前嘗試過(guò)用另外一種方法實(shí)現(xiàn)軟件的自動(dòng)安裝,這種方法不僅僅適用于msi,還適用于所有安裝文件。
    利用Windows的WMI服務(wù),可以對(duì)遠(yuǎn)程用戶(hù)的注冊(cè)表進(jìn)行操作,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce里面添加一個(gè)值為安裝文件路徑的字符串,就會(huì)在計(jì)算機(jī)啟動(dòng)并登錄后執(zhí)行該安裝文件,執(zhí)行完畢后會(huì)把這個(gè)鍵值刪除,也就是只執(zhí)行一次。
    利用PsTools,可以對(duì)遠(yuǎn)程計(jì)算機(jī)進(jìn)行重啟操作,當(dāng)計(jì)算機(jī)重啟后,用戶(hù)登錄時(shí),就會(huì)執(zhí)行安裝過(guò)程。如果不需要倒計(jì)時(shí)重啟,還可以通過(guò)WMI服務(wù)進(jìn)行重啟操作,這樣就可以完全通過(guò)Script來(lái)實(shí)現(xiàn),并且能夠記錄操作的成功與否。
    通過(guò)以下代碼可以連接遠(yuǎn)程計(jì)算機(jī):
    Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objSwbemLocator.ConnectServer(strComputer,"root\default",strUser,strPassword,"MS_409","ntlmdomain:")
    其中strComputer是遠(yuǎn)程計(jì)算機(jī)名,strUser是域管理員帳號(hào),strPassword是域管理員密碼
    得到objWMIService之后,就可以像對(duì)本機(jī)一樣操作WMI,例如獲取注冊(cè)表操作類(lèi)StdRegProv:
    Set objStdRegProv = objWMIService.Get("StdRegProv")
    關(guān)于遠(yuǎn)程注冊(cè)表操作可以查看MSDN里的StdRegProv類(lèi)說(shuō)明。
    通過(guò)Win32_OperatingSystem類(lèi)可以實(shí)現(xiàn)對(duì)遠(yuǎn)程計(jì)算機(jī)的關(guān)機(jī)、重啟等操作。
    WMI是個(gè)強(qiáng)大的工具,在局域網(wǎng)中可以實(shí)現(xiàn)很多方便的管理操作。但是需要通過(guò)VBScript來(lái)實(shí)現(xiàn),而VBScript的異常處理十分弱智;使用JScript的話,很多WMI類(lèi)的操作又十分繁瑣。
    posted @ 2008-06-14 16:12 amp@java 閱讀(1093) | 評(píng)論 (0)編輯 收藏

        JSF只能采用POST的方法進(jìn)行FORM提交,同一頁(yè)面要顯示不同的內(nèi)容,只有通過(guò)POST來(lái)改變參數(shù)或者通過(guò)SESSION傳遞變量。有時(shí)候有大量相似的頁(yè)面,這些頁(yè)面只有很少一部分不同(例如不同用戶(hù)、不同角色、不同頁(yè)碼等),通過(guò)跟在URL后面的query string本來(lái)可以很容易地實(shí)現(xiàn),但在JSF里卻不行,只要一提交,馬上就把?后面那串東西丟掉。假如有一個(gè)頁(yè)面,根據(jù)URL后面的id參數(shù)來(lái)顯示FORM的內(nèi)容,提交的時(shí)候如果驗(yàn)證出錯(cuò),那個(gè)FORM的內(nèi)容就丟失了,顯示一個(gè)莫名其妙的頁(yè)面,因?yàn)檫@時(shí)候那個(gè)id參數(shù)已經(jīng)沒(méi)有了。還有常用的分頁(yè)操作,本來(lái)在URL后面加上個(gè)頁(yè)碼就可以了,但是JSF的分頁(yè)控件卻只能通過(guò)POST來(lái)翻頁(yè),一刷新就出來(lái)個(gè)“重試”“取消”的對(duì)話框,讓人煩惱。如果頁(yè)面內(nèi)容根據(jù)不同用戶(hù)角色有細(xì)微不同,就得每個(gè)角色建立一個(gè)頁(yè)面,每個(gè)頁(yè)面對(duì)應(yīng)一個(gè)managed bean,這些頁(yè)面的內(nèi)容基本相同,bean的內(nèi)容也基本相同,卻要分別建立,一點(diǎn)重用的機(jī)會(huì)都沒(méi)有。今天做的一個(gè)東西就遇到了這種問(wèn)題:
    一個(gè)簡(jiǎn)單的審批流程,只有3個(gè)角色,申請(qǐng)者、審批者、執(zhí)行者,整個(gè)流程是這樣的:申請(qǐng)者填單->審批者查看并審批->執(zhí)行者執(zhí)行并填入結(jié)果->申請(qǐng)者查看。這樣,每種角色都有兩種列表:未回復(fù)和已回復(fù),這兩種列表在三個(gè)角色里面都是相似的,但有細(xì)微區(qū)別:
    申請(qǐng)者 審批者 執(zhí)行者
    未回復(fù)列表 自己已發(fā)出但未被執(zhí)行者執(zhí)行的列表 申請(qǐng)者已提交但自己未審批的列表 審批已通過(guò)但自己未執(zhí)行的列表
    已回復(fù)列表 自己已發(fā)出且執(zhí)行者已執(zhí)行的列表 申請(qǐng)者已提交且自己已審批的列表 審批已通過(guò)且自己已執(zhí)行的列表

    這些列表的不同之處在于:已登錄用戶(hù)的角色(可以從session中得到,但一個(gè)用戶(hù)可能有多種角色,他可能以不同的角色查看列表),列表的當(dāng)前狀態(tài)(對(duì)每種角色都有兩種狀態(tài)),列表的頁(yè)碼。由于每個(gè)列表都有可能有大量數(shù)據(jù),所以必須用到分頁(yè)。通過(guò)JSF的DataTable空間和DataScroller控件可以簡(jiǎn)單地實(shí)現(xiàn)分頁(yè),然而,這種分頁(yè)導(dǎo)致URL后面的參數(shù)無(wú)效了,這樣一來(lái),這六種列表就必須通過(guò)6個(gè)頁(yè)面來(lái)顯示了,通過(guò)頁(yè)面的名稱(chēng)來(lái)區(qū)分當(dāng)前用戶(hù)的角色、所查看的列表的狀態(tài),每個(gè)頁(yè)面通過(guò)POST來(lái)決定頁(yè)碼。本來(lái)一個(gè)頁(yè)面+一個(gè)bean+3個(gè)參數(shù)就可以決定,現(xiàn)在需要6個(gè)頁(yè)面+6個(gè)bean來(lái)完成了。

    list.jsp?type=0&role=0&page=1->type0_role0.jsp
    list.jsp?type=0&role=1&page=1->type0_role1.jsp
    list.jsp?type=0&role=2&page=1->type0_role2.jsp
    list.jsp?type=1&role=0&page=1->type1_role0.jsp
    list.jsp?type=1&role=1&page=1->type1_role1.jsp
    list.jsp?type=1&role=2&page=1->type1_role2.jsp

    假如有n種狀態(tài)m種角色那豈不是要n*m個(gè)頁(yè)面+n*m個(gè)bean?

    有點(diǎn)想放棄JSF這個(gè)雞肋了。

    希望有高手給條生路走走!
    posted @ 2008-06-04 19:48 amp@java 閱讀(2349) | 評(píng)論 (11)編輯 收藏

    剛剛才知道,原來(lái)Java的線程是不能重啟的,也就是說(shuō),當(dāng)線程的run()方法執(zhí)行到最后一行,退出之后,這個(gè)線程就結(jié)束了,不能再通過(guò)start()方法重啟啟動(dòng)這個(gè)線程,只能重新構(gòu)造一個(gè)線程對(duì)象,再調(diào)用其start()方法來(lái)啟動(dòng),但這個(gè)對(duì)象和原來(lái)那個(gè)對(duì)象已經(jīng)不同了。
    為了實(shí)現(xiàn)某個(gè)線程對(duì)象的“重啟”功能,可以在它的run()方法的最外層加上一個(gè)循環(huán)語(yǔ)句:
    1 public void run(){
    2   while(!stop){
    3     //do something
    4   }
    5 }

    這樣,只要stop不為true,run()方法就不會(huì)結(jié)束,不斷地“重啟”。
    如果run()方法里面還有一個(gè)循環(huán),那么就要兩個(gè)停止標(biāo)志:
    1 public void run(){
    2   while(!stop){
    3     //do something
    4     while(!stop && !restart){
    5       //do other thing
    6     }
    7   }
    8 }
    9 
    這樣,如果需要“重啟”線程,只要把restart設(shè)為true即可,如果要退出線程,只要把stop設(shè)為true即可。
    posted @ 2008-04-22 10:56 amp@java 閱讀(4187) | 評(píng)論 (0)編輯 收藏

    之前用過(guò)一個(gè)帶CheckBox的Tree控件,叫dhtmlXTree,支持xml數(shù)據(jù),功能很好很強(qiáng)大,但是有個(gè)問(wèn)題怎么也解決不了,不知道什么原因,就是第一次顯示的時(shí)候能夠正常顯示樹(shù)形列表,但第二次進(jìn)入相同頁(yè)面就會(huì)顯示錯(cuò)誤,所有圖片都看不見(jiàn),只看到其中的文字,而且這時(shí)候整個(gè)瀏覽器像死了一樣,點(diǎn)擊上面的任何鏈接都沒(méi)反應(yīng),必須關(guān)閉重新打開(kāi)才有效,或者等上十幾分鐘才反應(yīng)過(guò)來(lái),不知道是不是一直在后臺(tái)運(yùn)行某個(gè)Javascript腳本。雖然這個(gè)控件的源代碼可以看到,但是一條注釋都沒(méi)有,都不知道哪個(gè)部分出了問(wèn)題。

    在google上搜索替代方案時(shí),看到了BlueShoes的樹(shù)形控件,具有多種形態(tài),包括CheckBox,RadioButton等,每種形態(tài)都有例子,而且有詳細(xì)的規(guī)范的文檔(phpdocument,與JavaDoc類(lèi)似),關(guān)鍵是代碼里面也有詳細(xì)的注釋?zhuān)梢钥吹矫總€(gè)部分的實(shí)現(xiàn)原理。與dhtmlXTree使用XML存儲(chǔ)數(shù)據(jù)不同的是,這個(gè)樹(shù)形控件使用多維數(shù)組來(lái)存儲(chǔ)數(shù)據(jù),似乎可讀性和效率稍差,但出錯(cuò)的幾率也少了,不需要用到瀏覽器的XML處理。與前者一樣也支持IE5。

    關(guān)于BlueShoes的樹(shù)形控件的詳細(xì)的情況可以看這里:http://www.blueshoes.org/en/javascript/tree/

    那個(gè)網(wǎng)站上還有很多其他控件,也是很優(yōu)秀的,雖然它的后臺(tái)是php框架,但客戶(hù)端控件同樣可以用于JSP。
    posted @ 2008-02-26 11:28 amp@java 閱讀(457) | 評(píng)論 (0)編輯 收藏

    瀏覽器的緩存有時(shí)候顯得很討厭,明明已經(jīng)更新了內(nèi)容,就是不顯示新的,只要URL不變,瀏覽器就不會(huì)去檢查服務(wù)器是否已經(jīng)更新,而是用緩存里的東西,起碼在IE里是這樣。
    使用AJAX經(jīng)常需要?jiǎng)討B(tài)更新某一過(guò)程的狀態(tài),例如短信發(fā)送的狀態(tài),如果相隔幾秒查詢(xún)一次,URL不變的話,顯示出來(lái)的狀態(tài)永遠(yuǎn)不會(huì)改變,因?yàn)闉g覽器第一次獲取了內(nèi)容之后就不再更新了。
    為了解決這個(gè)問(wèn)題,最簡(jiǎn)單的辦法就是在URL后面加上一個(gè)不斷改變的查詢(xún)字符串(query string),例如:
    request.jsp?q=q&date=(new Date()).getTime()
    紅色部分就是不斷改變的查詢(xún)字符串。

    感謝http://wangcheng.javaeye.com/blog/135887的提示

    http://batmanwl.blog.sohu.com/71841783.html這里還可以看到多種解決方案
    posted @ 2008-02-26 10:33 amp@java 閱讀(812) | 評(píng)論 (1)編輯 收藏

    通過(guò)JavaME的WMA可選包發(fā)送短信時(shí),手機(jī)會(huì)提示是否允許程序發(fā)送該短信,雖然不太影響應(yīng)用,但每次都要按一下允許也很不爽。從網(wǎng)上看到有人說(shuō)對(duì)jar包簽名后就不會(huì)出現(xiàn)這種情況了,但是簽名的證書(shū)要向兩個(gè)大公司買(mǎi),因?yàn)槭謾C(jī)里面一般只內(nèi)置了那兩個(gè)大公司的根證書(shū),而且手機(jī)不允許安裝新的根證書(shū),這不分明是圈錢(qián)嗎?不知道當(dāng)初制定這個(gè)標(biāo)準(zhǔn)的家伙收了那兩個(gè)公司多少黑錢(qián)!雖然這樣會(huì)使很多病毒不能運(yùn)行,但是那兩個(gè)公司又不是上帝,給錢(qián)就可以買(mǎi)到證書(shū)了,他們又沒(méi)什么力量也不會(huì)去研究購(gòu)買(mǎi)證書(shū)的人要干什么,如果有惡意的人只要花點(diǎn)錢(qián),同樣可以造出帶簽名的病毒來(lái)。
    但是辦法總是有的,有人另辟蹊徑,通過(guò)非常手段給手機(jī)安裝一個(gè)自己制作的根證書(shū)。詳細(xì)過(guò)程可以看這里:http://browndrf.blogspot.com/,原理就是利用了NOKIA某些型號(hào)的手機(jī)可以通過(guò)web下載證書(shū)并安裝的漏洞。我實(shí)驗(yàn)了一下,整個(gè)過(guò)程其實(shí)不用那么復(fù)雜,不需要用到NOKIA的簽名工具,直接用SUN WTK的簽名工具就可以了,也不需要通過(guò)網(wǎng)絡(luò)安裝程序,跟平時(shí)安裝沒(méi)簽名的程序一樣。
    然而,簽了名的程序同樣需要確認(rèn)才能發(fā)送短信!而且比沒(méi)簽名的程序更麻煩,還要在MIDLet-Permissions里面填上一大堆許可,不簽名的軟件這個(gè)項(xiàng)根本不用填。唯一的好處是安裝的時(shí)候不會(huì)提示程序不受信任,而且不能用無(wú)簽名的同名程序覆蓋。但是這種安裝過(guò)程的問(wèn)題并不需要多大關(guān)注,因?yàn)榘惭b只是很少的時(shí)間,關(guān)鍵是使用。
    后來(lái)在這里:http://blog.csdn.net/zhengyun_ustc/archive/2006/04/07/654226.aspx又發(fā)現(xiàn)一篇文章,說(shuō)明能夠安裝根證書(shū)的不過(guò)是個(gè)別機(jī)型的漏洞,是不符合MIDP 2.0安全標(biāo)準(zhǔn)的,算了,這個(gè)問(wèn)題還是沒(méi)法解決,死心!
    JavaME真的有點(diǎn)像雞肋,它最大的優(yōu)點(diǎn)是跨平臺(tái),但各種手機(jī)的支持程度又各不相同,一點(diǎn)點(diǎn)小的差異就搞得人暈頭轉(zhuǎn)向。而且各種各樣的限制使得它最多就弄點(diǎn)小游戲玩玩,要連接網(wǎng)絡(luò)還得一堆的許可,程序大了還容易莫名其妙地崩潰。真是食之無(wú)味,棄之可惜。
    可是,我還是要搞……
    posted @ 2008-02-01 18:41 amp@java 閱讀(331) | 評(píng)論 (0)編輯 收藏

    Bouncy Castle(http://www.bouncycastle.org/)是一個(gè)龐大的加密類(lèi)庫(kù),支持Java和C#,其中Java部分發(fā)布的源代碼壓縮包就有24M左右,支持JDK 1.0~5.0,支持J2ME(現(xiàn)在叫JavaME)。
    但是,這個(gè)類(lèi)庫(kù)使用起來(lái)并不那么方便,它并沒(méi)有與普通Java類(lèi)庫(kù)那樣以Jar形式發(fā)布立即可用的二進(jìn)制類(lèi)庫(kù),而只發(fā)布源代碼,源代碼包含了多份,包括JDK1.0,JDK1.1,JDK1.2,JDK1.3,JDK1.4,JDK1.5,J2ME等,每種環(huán)境都有少量文件不一樣,有多個(gè)用于Ant的build xml,分別用于各種不同的JDK,但是每個(gè)xml定義了多個(gè)target,不知道哪個(gè)target才能build出可用的類(lèi)庫(kù)來(lái),選中了其中某個(gè)target有可能會(huì)出現(xiàn)錯(cuò)誤,build不下去。文檔太簡(jiǎn)單,基本沒(méi)講到怎么生成可用的類(lèi)庫(kù),網(wǎng)上的相關(guān)文檔也很少。我嘗試了兩天才終于把第一個(gè)MIDP加密測(cè)試程序運(yùn)行成功。
    我的應(yīng)用只是實(shí)現(xiàn)Java ME的加密,所以這里講的只是針對(duì)JavaME的,JavaSE應(yīng)該會(huì)簡(jiǎn)單一點(diǎn)。

    打開(kāi)下載下來(lái)的壓縮包(crypto-138.zip),會(huì)發(fā)現(xiàn)里面有一堆文件夾和一堆文件,其中一個(gè)文件夾叫j2me,于是第一反應(yīng)就是打開(kāi)它看看里面是什么,發(fā)現(xiàn)里面只有少量的源代碼文件,看來(lái)這只是適用于j2me的一部分源代碼而已,其他通用的部分不在這里。
    還有一個(gè)j2me.xml,是一個(gè)Ant的build文件,在eclipse里面用ant打開(kāi)以后,發(fā)現(xiàn)里面有很多target,除了what(輸出一些信息)和init(建立幾個(gè)目錄,復(fù)制一些文件)這兩個(gè)能執(zhí)行成功之外,其他幾乎都是失敗的,所以通過(guò)這個(gè)東西是搞不出我們可用的classes來(lái)的。
    沒(méi)辦法,只有一個(gè)個(gè)目錄地看,在一個(gè)zips目錄里面發(fā)現(xiàn)cldc_sources.zip,里面的源代碼文件有很多,有點(diǎn)像了,于是就把它解壓后放到一個(gè)Eclipse ME測(cè)試項(xiàng)目的src目錄下,找到org.bouncycastle.crypto.examples包,里面有個(gè)MIDPTest.java文件,還有個(gè)midp_test.jad,看來(lái)這個(gè)是用來(lái)測(cè)試用的MIDP了,調(diào)出WTK的模擬器來(lái)運(yùn)行一下,果然是,成功了。
    下一步是在手機(jī)上運(yùn)行。如果不混淆,生成的JAR包有1.6M之巨,不管了,先試一下。安裝到手機(jī)上,到最后出現(xiàn)“授權(quán)失敗”的提示,安裝不成功。記起原來(lái)找文檔時(shí)在index.html里面看到有這么一句話:The final caveat to this is that as the j2me distribution includes some compatibility classes starting in the java package, you need to use an obfuscator to change the package names before attempting to import a midlet using the BC API. 似乎因?yàn)橛糜趈2me的版本有幾個(gè)以java開(kāi)頭的包,里面包含了一些兼容類(lèi),可能是用于補(bǔ)充CLDC的不足,由于java開(kāi)頭的包是系統(tǒng)包,是不允許修改的,所以不處理過(guò)的話安裝會(huì)失敗。必須先用混淆器弄一下才行。Eclipse ME配置混淆器十分簡(jiǎn)單,我使用的是ProGuard。參照http://www.cnjm.net/eclipseme/docs/configuring.html配置即可。然后運(yùn)行Create Obfuscated Package生成混淆過(guò)的包,只有13K。安裝在Nokia 6681上,成功,運(yùn)行,也成功了。嘗試修改一下MIDPTest.java,在whichCipher方法里面,把返回值改為其他數(shù)字(0-4),就可以修改加密方式,但是由于DES加密使用的密鑰長(zhǎng)度為64bit,而默認(rèn)的key是"0123456789abcdef0123456789abcdef",運(yùn)行DES是會(huì)提示密鑰太長(zhǎng),我開(kāi)始以為把key改為4個(gè)字符就可以(因?yàn)镴ava使用Unicode,每個(gè)字符2字節(jié),4個(gè)字符8字節(jié)=64bit),卻出現(xiàn)了數(shù)組越界的異常,其實(shí)這個(gè)key并不是直接用作密鑰,還要經(jīng)過(guò)處理的。嘗試了8個(gè)字符也不行,最后發(fā)現(xiàn)16個(gè)字符就可以了,應(yīng)該是每?jī)蓚€(gè)字符對(duì)應(yīng)一個(gè)16進(jìn)制數(shù)。測(cè)試程序是對(duì)“www.bouncycastle.org”這個(gè)字符串進(jìn)行加密和解密,速度還是挺快的,幾乎感覺(jué)不到需要時(shí)間(在手機(jī)上啟動(dòng)Java程序本來(lái)就比較慢)。

    中間還碰到一個(gè)問(wèn)題,由于我是把源代碼直接復(fù)制到一個(gè)原來(lái)建立好的MIDP項(xiàng)目里,那個(gè)MIDP項(xiàng)目里已經(jīng)有個(gè)默認(rèn)的JAD文件,但是里面沒(méi)有表示要運(yùn)行的Midlet,生成Jar包之后,安裝到手機(jī)上到最后會(huì)出現(xiàn)安裝文件無(wú)效的提示。打開(kāi)那個(gè)JAD文件,在Midlets標(biāo)簽里點(diǎn)擊Add按鈕,把org.bouncycastle.crypto.examples.MIDPTest添加進(jìn)去即可。

    以上測(cè)試使用的環(huán)境是:
    JDK 1.5.02
    Eclipse 3.2.0
    Eclipse ME 1.7.7 http://eclipseme.org
    Sun WTK 2.5.2 for CLDC
    ProGuard 4.1 http://proguard.sourceforge.net/



    剛剛發(fā)現(xiàn)Bouncy Castle的下載頁(yè)面http://www.bouncycastle.org/latest_releases.html里面有專(zhuān)用于J2ME的源代碼發(fā)行包,里面只包含用于J2ME的代碼,如果僅用在J2ME下的話,這個(gè)應(yīng)該比較簡(jiǎn)單,不用找半天。
    posted @ 2008-01-25 19:59 amp@java 閱讀(1448) | 評(píng)論 (1)編輯 收藏

    有時(shí)候我們需要通過(guò)程序自動(dòng)發(fā)送一些純文字的信息,通過(guò)SMS可以達(dá)到目的,但當(dāng)文字達(dá)到一定長(zhǎng)度時(shí),就必須分割成多條短信(一般60漢字一條),增加了費(fèi)用,通過(guò)MMS可以解決這一問(wèn)題,MMS最大支持100KB的內(nèi)容,假設(shè)每個(gè)漢字3byte(使用UTF-8編碼),能發(fā)送33K個(gè)漢字,一次可以發(fā)送一篇文章了。
    Now SMS/MMS提供了一個(gè)Web界面用于發(fā)送彩信,通過(guò)Apache HttpClient,我們可以模擬瀏覽器的行為向web服務(wù)器提交表單,發(fā)送彩信。Now SMS/MMS的Web界面提供了很多選項(xiàng),但發(fā)送純文字彩信的話我們只需要填寫(xiě)接收者,主題(可選),內(nèi)容即可,把對(duì)應(yīng)的表單內(nèi)容POST到當(dāng)前頁(yè)面,就能發(fā)送一條彩信。(待續(xù))
    posted @ 2007-10-01 14:22 amp@java 閱讀(1162) | 評(píng)論 (0)編輯 收藏

    Now SMS/MMS是一個(gè)強(qiáng)大的短信/彩信發(fā)送服務(wù)器,它內(nèi)置了彩信中心,在某些運(yùn)營(yíng)商的網(wǎng)絡(luò)內(nèi)可以通過(guò)普通的短信貓發(fā)送彩信,而不需要使用支持GPRS的短信貓,也就是說(shuō)系統(tǒng)本身就具有了運(yùn)營(yíng)商的彩信中心的功能。然而,在中國(guó)移動(dòng)的網(wǎng)絡(luò)內(nèi)是不能實(shí)現(xiàn)這種方式發(fā)送彩信的,必須通過(guò)移動(dòng)夢(mèng)網(wǎng)的彩信中心轉(zhuǎn)發(fā)。
    彩信的發(fā)送其實(shí)是兩個(gè)過(guò)程:
    1、向目標(biāo)手機(jī)發(fā)送一條普通的提醒短信,其中包含了發(fā)送者號(hào)碼、彩信的URL等信息,該URL指向彩信中心的某個(gè)web目錄下的某個(gè)彩信文件;
    2、目標(biāo)手機(jī)接收到這條提醒短信后,主動(dòng)發(fā)起GPRS連接,根據(jù)短信中的URL向彩信中心提取該彩信,并顯示出來(lái)。
    Now SMS/MMS 自帶的彩信中心其實(shí)就是一個(gè)支持手機(jī)連接的web服務(wù)器,它把制作好的彩信放在某個(gè)web目錄下,手機(jī)連接時(shí)就可以下載。
    然而,實(shí)踐證明,如果使用中國(guó)移動(dòng)的SIM卡,無(wú)論使用的是什么短信貓,都不能通過(guò)系統(tǒng)自帶的彩信中心發(fā)送彩信。
    要設(shè)置成通過(guò)移動(dòng)公司的彩信中心發(fā)送彩信,必須把系統(tǒng)的默認(rèn)設(shè)置——使用自帶的MMSC(彩信中心)——改為使用移動(dòng)公司的MMSC。方法如下:
    在Now SMS/MMS Gateway配置程序中選擇MMSC Routing,然后點(diǎn)擊Add按鈕,在彈出的對(duì)話框中建立一個(gè)新的MMSC配置,其中Acount Name和Account Description可以隨便填,只是用來(lái)識(shí)別配置名稱(chēng),因?yàn)橄到y(tǒng)可以設(shè)置多個(gè)MMSC。Default Sender Address必須留空,否則發(fā)送很難成功(有極少部分能夠發(fā)送成功)。Allow Sender Address Override前的復(fù)選框也必須留空。Route messages to this account for recipient phone number(s)不用填(這是一個(gè)掩碼,只有符合要求的號(hào)碼才用這個(gè)路由,按照官方文檔的說(shuō)法,不填的話是不會(huì)用這個(gè)路由的,但實(shí)際上把它設(shè)成默認(rèn)路由的話,即使不填也會(huì)用這個(gè),也許填上+861*,1*會(huì)好些,表示中國(guó)的手機(jī)都用這個(gè)發(fā))。Route messages to VASP via選擇MM1,之后會(huì)出現(xiàn)更多的輸入框,點(diǎn)擊Look up Operator Seetings,出現(xiàn)一個(gè)選擇運(yùn)營(yíng)商的對(duì)話框,很幸運(yùn),中國(guó)移動(dòng)在里面,選擇China - China Mobile,然后OK即可,系統(tǒng)自動(dòng)把適合中國(guó)移動(dòng)的內(nèi)容填了進(jìn)去。但是Network Connection和Modem Used兩個(gè)下拉列表還沒(méi)選好。這里必須使用對(duì)應(yīng)的GPRS貓的調(diào)制解調(diào)器(在控制面板-電話和調(diào)制解調(diào)器選項(xiàng)-調(diào)制解調(diào)器-添加,按照提示一步步就能找到GPRS貓,看好哪個(gè)調(diào)制解調(diào)器對(duì)應(yīng)哪個(gè)端口,從而知道哪個(gè)調(diào)制解調(diào)器對(duì)應(yīng)哪個(gè)GPRS貓)。填好這些東西后點(diǎn)擊Test Connection可以檢測(cè)連接,成功就可以了,檢測(cè)時(shí)間比較長(zhǎng),要耐心等待。填好之后點(diǎn)擊OK,在MMSC Routing標(biāo)簽頁(yè)里的Additional Routes里面就能看到剛才的那個(gè)配置名稱(chēng),然后在Default Route里面選擇剛才的配置名稱(chēng)作為默認(rèn)路由就可以了。
    之后打開(kāi)MMSC標(biāo)簽,配置自帶的MMSC。雖然我們使用的是中國(guó)移動(dòng)的MMSC,但通過(guò)web發(fā)送彩信時(shí),必須先發(fā)送到系統(tǒng)自帶的MMSC,再轉(zhuǎn)發(fā)到移動(dòng)的MMSC,所以必須把系統(tǒng)的MMSC也配置好。這里就是普通web服務(wù)器的配置(還有SMTP的配置,可選),把端口和IP選好后,還要注意Local Host Name or IP Address里要填入一個(gè)本機(jī)的IP,如果在僅在內(nèi)網(wǎng)使用,可以直接填本機(jī)IP(外網(wǎng)的情況沒(méi)有研究過(guò),看看說(shuō)明書(shū)先)。其他默認(rèn)的就可以了。
    再打開(kāi)Web標(biāo)簽頁(yè),把Web服務(wù)器配置好。
    打開(kāi)瀏覽器,輸入http://服務(wù)器IP:web服務(wù)器端口/,就能看到發(fā)送各種短信、彩信的鏈接,然后就可以發(fā)送彩信進(jìn)行測(cè)試了。如果發(fā)送不成功,可以打開(kāi)Serial #標(biāo)簽頁(yè),把底下的三個(gè)Debug選項(xiàng)都勾上,再發(fā)送一下,然后在Now SMS/MMS 的安裝目錄下找到MMSCDEBUG.LOG等幾個(gè)LOG文件查看究竟是什么問(wèn)題。文件太大會(huì)導(dǎo)致發(fā)送失敗,系統(tǒng)不會(huì)自動(dòng)檢查的。文件大小的上限還不清楚,但超過(guò)100KB似乎就肯定不行。
    今天搞了一天這個(gè)東西,終于能正常發(fā)送彩信了。在這里備忘一下。慢慢再作深入研究。


    感謝:http://blog.csdn.net/phiger/archive/2006/12/19/1449176.aspx

    官方文檔:http://www.nowsms.com/documentation/ProductDocumentation/mms_notifications_and_content/Connecting_to_operator_MMSC.htm#SendingMMSMessages
    posted @ 2007-09-18 19:32 amp@java 閱讀(5406) | 評(píng)論 (18)編輯 收藏

    主站蜘蛛池模板: 亚洲中文字幕无码一去台湾| 日韩免费电影网站| 免费a级黄色毛片| 婷婷亚洲综合五月天小说在线| 免费观看的毛片手机视频| 亚洲色精品VR一区区三区| 69成人免费视频无码专区| 亚洲女女女同性video| 永久免费视频v片www| 国产AV无码专区亚洲AV麻豆丫 | 亚洲乱码中文字幕久久孕妇黑人| rh男男车车的车车免费网站| 国产亚洲精久久久久久无码AV| v片免费在线观看| 亚洲毛片网址在线观看中文字幕| www在线观看播放免费视频日本| 国产亚洲成人在线播放va| 成全在线观看免费观看大全| 亚洲AV本道一区二区三区四区 | 亚洲天堂久久精品| 免费看片在线观看| 亚洲熟伦熟女专区hd高清| 日韩精品视频免费观看| 免费很黄无遮挡的视频毛片| 亚洲乱码国产一区网址| 成人A片产无码免费视频在线观看| 亚洲午夜精品一区二区| 99在线精品免费视频九九视| 亚洲欧美不卡高清在线| 又大又硬又爽免费视频| 伊人久久国产免费观看视频| 亚洲国产另类久久久精品黑人| 一区二区免费视频| 国产精品亚洲综合五月天| 在线观看国产情趣免费视频| 一级做a爰片性色毛片免费网站| 亚洲精品国产美女久久久| 91精品国产免费网站| 亚洲综合在线一区二区三区| 免费大学生国产在线观看p| 91成人免费观看在线观看|