amp@java

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

          2008年6月14日 #

          當(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)缺失,于是回車修復(fù),但每次修復(fù)完,重新檢測(cè)還是那樣,而且沒(méi)有提示USB控制器驅(qū)動(dòng)安裝有問(wèn)題,有些功能用鍵盤(pán)無(wú)法操作,不知道是不是還有哪里可以操作一下,于是又搜了一下,如何用鍵盤(pán)代替鼠標(biāo),居然真的找到了!
          4、按WIN鍵,輸入設(shè)置,回車,打開(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 閱讀(1158) | 評(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 閱讀(2259) | 評(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 閱讀(406) | 評(píng)論 (0)編輯 收藏

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

          花了不少時(shí)間才搞定,有幾個(gè)地方需要注意:
          1、如果表單數(shù)據(jù)不包含中文,直接把表單的Name和Value加在HttpPost的URL的?后面即可,不需要專門(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 閱讀(3576) | 評(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 閱讀(3606) | 評(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í)候,用戶要關(guān)閉程序,就必須馬上停止線程,如果用戶需要暫停檢測(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)擊按鈕之后,用戶最多要等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)很方便,如下圖所示:

          可以選擇把所有類庫(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ì)普通用戶來(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 閱讀(5144) | 評(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 閱讀(10433) | 評(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ù)字類型,就會(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)品名稱怎么表示呢?如下圖表中所示。

               公式=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è)銷售額的提成比率和提成額。

              

             公式:=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é)果為:

                 {"銷售張一",1;"銷售趙三",5;"人事楊五",3;"銷售趙三",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 閱讀(521) | 評(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 閱讀(7277) | 評(píng)論 (0)編輯 收藏

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

          這類應(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)行電腦的客戶端,手機(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 閱讀(1725) | 評(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 閱讀(15650) | 評(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的客戶端和Oracle 10g的客戶端,并分別設(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)程序選擇類似“Oracle in OraClient10g_home1”的,確定之后輸入Data Source Name(隨意),Description(隨意),TNS Service Name(在企業(yè)管理器里設(shè)置好的連接名),User ID(用戶名),然后按Test Connection測(cè)試是否連接成功,成功之后點(diǎn)OK;
          3、在SQL Server 2000的企業(yè)管理器里,在任意一個(gè)表上點(diǎn)右鍵,所有任務(wù),導(dǎo)出數(shù)據(jù),在目的里選擇“Oracle in OraClient10g_home1”,用戶/系統(tǒng)DSN里面就會(huì)出現(xiàn)剛才設(shè)置好的DSN名字,選中,然后輸入用戶名密碼,點(diǎn)兩次下一步就會(huì)出現(xiàn)選擇源表和視圖對(duì)話框
          4、這里要注意的是,勾上源中的某個(gè)表,在目的里面就會(huì)出現(xiàn)"用戶名"."表名"的默認(rèn)選項(xiàng),如果你剛才使用的Oracle用戶名是小寫(xiě)的話,這里也會(huì)是小寫(xiě),一定要改成大寫(xiě),否則會(huì)提示該用戶名不存在

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

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

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

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

           

          在安裝這些組件之前,將無(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 閱讀(2566) | 評(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ù)類型就是byte,short,int,long這幾個(gè),長(zhǎng)度分別為1,2,4,8字節(jié),C/C++可以用typedef定義各種數(shù)據(jù)類型。

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

          把一個(gè)整數(shù)從0一直往上加1,加到溢出就變成了負(fù)數(shù)的最小值,然后再繼續(xù)加1,最后又能回到0,實(shí)際上就是一個(gè)輪回。
          例如一個(gè)byte類型的整數(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類型的值都轉(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類型的值,如果要賦給byte類型的c,必須顯式地進(jìn)行類型轉(zhuǎn)換,即把第二句改為:
          c=(byte)(a+b)

          這一點(diǎn)很關(guān)鍵,因?yàn)閷?duì)于一個(gè)最高位為1的byte類型的整數(shù)(負(fù)數(shù)),在運(yùn)算之前它會(huì)被強(qiáng)制轉(zhuǎn)換成int類型,根據(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類型再參加運(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)表示一個(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ù)類型:
          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 閱讀(1844) | 評(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)目依賴的檢測(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的類型是TableEditor,controls的類型是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è)類似路由器的虛擬網(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,以此類推,最多可以同時(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表示模擬器名稱。
          實(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 閱讀(2415) | 評(píng)論 (0)編輯 收藏

          前天是情人節(jié),雖然結(jié)婚好多年了,但是老婆一直都喜歡驚喜的浪漫,可惜我卻是個(gè)木訥的呆子,做不出那些轟動(dòng)的事情。那天下午馬上就要下班回家了,突然在微博上看到有人談到geek的情人節(jié)禮物,雖然我不是geek,但是最近在學(xué)Android,老婆的手機(jī)也是Android系統(tǒng)的,何不專門(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 閱讀(2296) | 評(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 閱讀(1379) | 評(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的解釋,handler所在的線程跟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 閱讀(1838) | 評(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的類
          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)稱性能超過(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://www.aygfsteel.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)代表了名稱為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的注釋,從IE 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è)病毒惹的禍,下載了專殺工具回來(lái)查了一下,果然找到了兩個(gè)被感染的文件,一個(gè)是jpg文件,在IE的緩存里,一個(gè)是dll文件,在system32里。
          根據(jù)dll文件名在注冊(cè)表里查到了它注冊(cè)的服務(wù),原來(lái)又是之前處理過(guò)的那種,服務(wù)名隨機(jī)、服務(wù)描述為空、啟動(dòng)類型為自動(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 閱讀(11966) | 評(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è)專門(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ī)的名稱一樣。一般來(lái)說(shuō),在局域網(wǎng)里面,計(jì)算機(jī)名稱是與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)情況下,即使輸入了正確的用戶名和密碼,系統(tǒng)也會(huì)提示“用戶口令錯(cuò)誤”,讓人十分困惑。其實(shí)真實(shí)的原因是,你輸入的用戶必須在“作為批處理作業(yè)登錄”里面,否則就會(huì)出現(xiàn)上述錯(cuò)誤。操作方法如下:運(yùn)行-gpedit.msc-計(jì)算機(jī)配置-Windows設(shè)置-安全設(shè)置-本地策略-用戶權(quán)利指派-作為批處理作業(yè)登錄-添加用戶或組...-加入要登錄的用戶。
          執(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è)帳戶,這是我第一次登錄PT站。每個(gè)文件都有幾個(gè)甚至幾十個(gè)種子在等待下載者,真是“僧多粥少”。下載速度果然很猛,下了幾個(gè)文件,基本上可以達(dá)到ADSL的上限,甚至遇到了前所未有的極速,不過(guò)持續(xù)時(shí)間較短,但是平均速度都接近上限。
          然而,ADSL小水管終究不是玩PT的料,嚴(yán)格的分享率要求和ADSL龜速的上傳帶寬使得我兩天之后就變成了冰人,如果20天之內(nèi)再不提高分享率,我的帳戶將會(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)法比的。
          還是等到哪一天光纖到戶再玩PT吧,現(xiàn)在的任務(wù)就是趁著20天沒(méi)過(guò),趕緊“過(guò)癮”,嘿嘿!
          posted @ 2009-09-14 19:44 amp@java 閱讀(295) | 評(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,因此還需要找到專門(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 閱讀(41556) | 評(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ī)牌。
          然而,專業(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”類似的設(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 閱讀(5941) | 評(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)編輯 收藏

          為了充分利用晚上的帶寬,我搞了一部專門(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)了一下真的有賣的,還比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ō)他賣不了這個(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 閱讀(3467) | 評(píng)論 (11)編輯 收藏

          這幾天要在單位部署一個(gè)軟件包,是msi形式的,據(jù)說(shuō)可以通過(guò)“域推送”的形式安裝,搜索了一下,發(fā)現(xiàn)需要在 組策略->軟件設(shè)置->軟件安裝 里面添加放在共享目錄里的軟件包。但是我試過(guò)無(wú)論在“計(jì)算機(jī)配置”里面還是在“用戶配置”里面添加那個(gè)軟件包,無(wú)論是“發(fā)布”還是“指派”,都沒(méi)辦法自動(dòng)安裝,最多只是在“添加刪除程序”里面的“添加新程序”出現(xiàn)那個(gè)軟件包,還需要手動(dòng)安裝。
          域控制器上按照部門(mén)劃分了多個(gè)組織單位(OU),并把用戶分配到各自的組織單位中,組策略就是在這些組織單位上面應(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)用于用戶,實(shí)際上是“用戶配置”應(yīng)用于用戶,“計(jì)算機(jī)配置”應(yīng)用于計(jì)算機(jī),要對(duì)讓每臺(tái)計(jì)算機(jī)自動(dòng)安裝,而不是在用戶登錄之后安裝,就必須在“計(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)程用戶的注冊(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ī)重啟后,用戶登錄時(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è)表操作類StdRegProv:
          Set objStdRegProv = objWMIService.Get("StdRegProv")
          關(guān)于遠(yuǎn)程注冊(cè)表操作可以查看MSDN里的StdRegProv類說(shuō)明。
          通過(guò)Win32_OperatingSystem類可以實(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類的操作又十分繁瑣。
          posted @ 2008-06-14 16:12 amp@java 閱讀(1093) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 丰原市| 大悟县| 兰州市| 肃宁县| 西藏| 武冈市| 泽普县| 日土县| 湖口县| 万载县| 布尔津县| 额尔古纳市| 安乡县| 湟源县| 莲花县| 徐水县| 商丘市| 阿巴嘎旗| 贞丰县| 龙海市| 象州县| 巴彦淖尔市| 鄯善县| 荥阳市| 道真| 页游| 博爱县| 望城县| 赣州市| 临武县| 鄱阳县| 临邑县| 绍兴市| 邻水| 成都市| 苍溪县| 石门县| 抚松县| 游戏| 拉孜县| 长兴县|