莊周夢(mèng)蝶

          生活、程序、未來(lái)
             :: 首頁(yè) ::  ::  :: 聚合  :: 管理

              越來(lái)越覺(jué)的JRuby是個(gè)很有前途的項(xiàng)目,結(jié)合Ruby的性感語(yǔ)法和java極其豐富的類(lèi)庫(kù),況且有團(tuán)隊(duì)持續(xù)不斷地修正bug、改進(jìn)性能,這樣的玩意完全有成為“少男殺手”的潛質(zhì)。JRuby wiki上列出了性能優(yōu)化的四條建議:
          1、調(diào)優(yōu)編譯器,JRuby早就棄暗投明跟隨XRuby走上了編譯這條牛B的道路,將Ruby Script編譯成字節(jié)碼,因此這個(gè)環(huán)節(jié)是斷斷不能忽略的。
          兩種編譯方式:
          AOT模式:直接生成class文件,脫了Ruby這層皮,咱就是人見(jiàn)人“愛(ài)”的java了。
          JIT模式:充分利用成熟的jit技術(shù),咱不全脫,朦朧美才是真的美。默認(rèn)從0.9.9版本開(kāi)始就是開(kāi)啟的,關(guān)閉的話(要我說(shuō)還不如全脫)
          jruby -J-Djruby.jit.enabled=false


          2、關(guān)閉ObjectSpace
          ObjectSpace是Ruby用來(lái)操作所有運(yùn)行時(shí)對(duì)象的模塊,這個(gè)功能相當(dāng)牛x。這個(gè)的實(shí)現(xiàn)在c ruby里是比較容易的,但是對(duì)于JRuby代價(jià)就比較昂貴了,其實(shí)就大部分情況下你基本用不到這個(gè)東東,那么最好就是關(guān)閉它,JRuby提供了
          jruby -J-Djruby.objectspace.enabled=false
          選項(xiàng)來(lái)關(guān)閉它。

          3、開(kāi)啟線程池
          我們知道,在c ruby中的線程是綠色的輕量級(jí)線程,因此運(yùn)行時(shí)就動(dòng)不動(dòng)開(kāi)個(gè)百來(lái)十個(gè)“線程”跑一跑充下款爺;然而在JRuby中,線程的實(shí)現(xiàn)那可是實(shí)打?qū)嵉谋镜鼐€程(也就是Ruby線程與java線程一比一),你這么動(dòng)不動(dòng)上百個(gè)線程那不慢才怪了。因此JRuby提供了線程池選項(xiàng),運(yùn)行時(shí)盡可能地滿足你的要求開(kāi)線程,但是當(dāng)短命的Ruby線程重復(fù)創(chuàng)建的時(shí)候,這些線程將被復(fù)用,這在大多數(shù)情況下能提高性能表現(xiàn),特別是在每次調(diào)用都啟動(dòng)一個(gè)線程的情況下。不過(guò)具體效果還是要測(cè)試的實(shí)際數(shù)據(jù)說(shuō)話。
          jruby -J-Djruby.thread.pooling=true


          4、使用Java "server"模式虛擬機(jī),地球淫都知道
          jruby -J-server myscript.rb

          5、盡量使用最新的jdk,在我的測(cè)試中,jdk6跑jruby是效率最高的。

          posted @ 2008-01-31 18:58 dennis 閱讀(4420) | 評(píng)論 (1)編輯 收藏

          class BitStruct
            
          def self.list(name,element)
              module_eval 
          <<-HERE
                rest :body
                
          def #{name.to_s}=(elist)
                   e=Object.const_get(:#{element})
                   if elist.respond_to? :each and elist.respond_to? :[] and elist[0].is_a? e
                      elist.each{ 
          |value| self.body+=value}
                   elsif elist.is_a? e
                      self.body
          =elist
                   
          else
                      
          raise ArgumentError,elist.to_s<<" is not a #{element}",caller
                   end
                end
                
          def #{name.to_s}
                   result=[]
                   e
          =Object.const_get(:#{element})
                   size=e.new.size
                   num
          =self.body.size/size-1
                   
          for i in 0..num
                      result[i]
          =e.new(self.body[i*size,size])
                   end
                   result
                end
              HERE
            end
          end
          利用Ruby的動(dòng)態(tài)特性,很容易就達(dá)到了,使用的話:

          class A <BitStruct
             unsigned :id,
          32
          end
          class B<BitStruct
             list :aList,A
          end
          alist
          =[]
          for i in 0..10
            a
          =A.new
            a.id
          =i
            alist.unshift a
          end
          b
          =B.new
          b.aList
          =alist
          b.aList.each{
          |e| puts e.id}

          posted @ 2008-01-27 15:53 dennis 閱讀(366) | 評(píng)論 (0)編輯 收藏

              分析二進(jìn)制協(xié)議或者存取二進(jìn)制文件是個(gè)很常見(jiàn)的需求,Ruby的IO提供了對(duì)二進(jìn)制的讀操作,但是寫(xiě)入?yún)s只提供字符。并且讀的操作也比較笨拙,例如,在c里面的話,我們一般是定義個(gè)struct,然后:

          fread(record, sizeof(record), 1, stream);

          在java里,也是比較容易,特別是nio引入了ByteBuffer之后就更方便了。Ruby的話,我得自己確定讀多少個(gè)字節(jié),并自己“組裝”成原始數(shù)據(jù),這顯然太麻煩了,幸好,我們有bit-struct :)
              到主頁(yè)下載,解壓之后參照README安裝下就OK了。使用的話,也是先定義結(jié)構(gòu),然后new就行了:
          require 'bit-struct'
          class Message < BitStruct
              signed :msg_length,
          32
              
          char   :type,24
              signed :uid,
          32
              unsigned :cmd,
          16
              rest  :body
          end
          msg
          =Message.new
          file.read(msg)
          p msg.inspect

          bit-struct支持float,char,unsigned,signed,text,pad,nest,oct,hex,其中nest用于聲明一個(gè)嵌套結(jié)構(gòu),例如:
          class Sub < BitStruct
              unsigned :x,    
          8
           end

          class A < BitStruct
              nest    :n,  Sub
          end

          = A.new
          p a  
          # ==> #<A n=#<Sub x=0>>

          如果你看下源碼的話,會(huì)發(fā)現(xiàn)BitStruct繼承String類(lèi),因此IO可以直接將BitStruct寫(xiě)入文件,內(nèi)部自動(dòng)幫你處理轉(zhuǎn)換細(xì)節(jié)。

          posted @ 2008-01-25 18:56 dennis 閱讀(1679) | 評(píng)論 (0)編輯 收藏

          天涯上的牛人真多



          posted @ 2008-01-22 14:12 dennis 閱讀(441) | 評(píng)論 (0)編輯 收藏

              我從來(lái)就不是很安分的人,來(lái)福州兩個(gè)月了,在star-net也干了兩個(gè)月,最后還是經(jīng)不住誘惑決定去廣州了。原因?怎么說(shuō)呢,在福州的工作沒(méi)有我想象中的有趣,做的東西都是比較事務(wù)性,或者說(shuō)沒(méi)有激起我的熱情。不過(guò)對(duì)于在福建的來(lái)說(shuō),star-net應(yīng)該還是很好的選擇。提辭職對(duì)于公司來(lái)說(shuō)挺突然的,不過(guò)我做事情從來(lái)都是仔細(xì)考慮過(guò)后才會(huì)決定的,如果沒(méi)有想好就提的話難免讓人以為我在要挾什么的。廣州那邊其實(shí)很早就聯(lián)系了,因?yàn)閙ryufeng老大在那,他幫我推薦了下,很感激老大。說(shuō)起來(lái)跟mryufeng老大認(rèn)識(shí)還通過(guò)javaeye,在javaeye上真認(rèn)識(shí)了不少人。去廣州的話,很有可能是做服務(wù)器開(kāi)發(fā),主要是java,可能用到cpp、erlang、腳本語(yǔ)言等等,可以說(shuō)是混合性比較強(qiáng)的工作,不過(guò)也有可能去做web開(kāi)發(fā),這塊畢竟是我一直在做的。還是希望能跳出web這個(gè)領(lǐng)域,我的興趣還是在并發(fā)和服務(wù)器上。
              明天晚上坐長(zhǎng)途班車(chē)出發(fā),后天一早到廣州,準(zhǔn)備投靠一哥們,這哥們還是大學(xué)時(shí)玩網(wǎng)絡(luò)游戲認(rèn)識(shí)的。在游戲里很投緣,這廝一個(gè)人從唐山跑到廣州混了兩年了,而且混的挺好,不得不讓我佩服。先去投靠他幾天,然后慢慢找房子,14號(hào)就正式去上班了。去了潛心好好干,好好向公司里的老大們學(xué)習(xí),畢竟是我最感興趣的領(lǐng)域啊,機(jī)會(huì)難得。

          posted @ 2008-01-11 15:58 dennis 閱讀(622) | 評(píng)論 (3)編輯 收藏

              smartclient是一個(gè)企業(yè)級(jí)的ajax框架,包括非常出色的UI庫(kù)、工具庫(kù)和客戶端服務(wù)端數(shù)據(jù)綁定等功能。smartclient本來(lái)是一個(gè)商業(yè)產(chǎn)品, 2007年11月7號(hào)才以LGPL協(xié)議開(kāi)源。除了一些所見(jiàn)即所得的構(gòu)建工具和企業(yè)級(jí)的可選組件外,其他都開(kāi)源了。這個(gè)記的javaeye和infoq都有報(bào)道。
              在接觸smartclient以前,我還沒(méi)有使用過(guò)類(lèi)似的ajax ui庫(kù),比如現(xiàn)在很火的ext。smartclient給我的第一印象是非常漂亮的ui效果,有興趣可以去它的官方demo看看。smartclient的demo和文檔做的非常出色,入手開(kāi)發(fā)也非常容易。
          第一步:下載LGPL版本,并解壓縮
          第二步:運(yùn)行解壓后目錄下的\SmartClient_60_LGPL\smartclientSDK\start_embedded_server.bat,SDK自帶了一個(gè)內(nèi)嵌的tomcat
          第三步:訪問(wèn) http://localhost:8080

          你將見(jiàn)到:


          這些demo本身就是用smartclient制作的。開(kāi)發(fā)過(guò)程中你需要做就是查看examples和文檔中的reference(api文檔),基本沒(méi)有解決不了的問(wèn)題。

          人見(jiàn)人愛(ài)的Hello World例子:
          isc.Label.create({
              height: 
          50,
              styleName: 
          "helloWorldText",
              padding: 
          4,
              backgroundColor: 
          "#ffffd0",
              align: 
          "center",
              valign: 
          "center",
              wrap: 
          false,
              showEdges: 
          true,
              showShadow: 
          true,
              contents: 
          "Hello world!"
          })

          效果:


              smartclient除了完整的UI組件,還包括豐富的動(dòng)態(tài)效果庫(kù)以及可選的皮膚等高級(jí)主題,不再展開(kāi)了,畢竟貼圖是在是挺麻煩的事情:)還不如有興趣的自己翻demo。說(shuō)了這么多優(yōu)點(diǎn),那么缺點(diǎn)是啥?你可能猜到了,性能!所有js UI庫(kù)無(wú)法避免的問(wèn)題,不過(guò)我沒(méi)有其他UI庫(kù)的使用經(jīng)驗(yàn),倒是不能給出個(gè)比較數(shù)據(jù)。我們寫(xiě)的東西的性能也只是堪堪能夠接受。
             smartclient跟dwr可以說(shuō)是天生一對(duì),smartclient UI組件的數(shù)據(jù)源可以是xml也可以是json,如果采用json做交換格式,可以與dwr無(wú)縫結(jié)合,真正實(shí)現(xiàn)One Page,One Application(我們就是這樣做的^_^)。






          posted @ 2008-01-08 15:48 dennis 閱讀(7499) | 評(píng)論 (1)編輯 收藏

              《編程珠璣》第一章第一題就相當(dāng)?shù)木剩鰝€(gè)筆記。題目如下:
          輸入:   一個(gè)包含n個(gè)正整數(shù)的文件,每個(gè)正整數(shù)小于n,n等于10的7次方(一千萬(wàn))。并且文件內(nèi)的正整數(shù)沒(méi)有重復(fù)和關(guān)聯(lián)數(shù)據(jù)。

          輸出:  輸入整數(shù)的升序排列
           
          約束: 限制在1M左右內(nèi)存,充足的磁盤(pán)空間

              假設(shè)整數(shù)占32位,1M內(nèi)存可以存儲(chǔ)大概250000個(gè)整數(shù),第一個(gè)方法就是采用基于磁盤(pán)的合并排序算法,第二個(gè)辦法就是將0-9999999切割成40個(gè)區(qū)間,分40次掃描(10000000/250000),每次讀入250000個(gè)在一個(gè)區(qū)間的整數(shù),并在內(nèi)存中使用快速排序。書(shū)中提出的第三個(gè)解決辦法是采用bitmap(或者稱為bit vector)來(lái)表示所有數(shù)據(jù)集合(注意到條件,數(shù)據(jù)沒(méi)有重復(fù)),這樣就可以一次性將數(shù)據(jù)讀入內(nèi)存,減少了掃描次數(shù)。算法的偽代碼如下:
          階段1:初始化一個(gè)空集合
               for i=[0,n)
                     bit[i]=0;
          階段2:讀入數(shù)據(jù)i,并設(shè)置bit[i]=1
              for each i in the input file
                     bit[i]=1;
          階段3:輸出排序的結(jié)果
             for i=[0,n)
                    if bit[i]==1
                        write i on the output file

          這個(gè)算法的時(shí)間復(fù)雜度在O(n),用c語(yǔ)言寫(xiě)的版本可以在10秒內(nèi)完成任務(wù)!c語(yǔ)言的源碼在該書(shū)主頁(yè)上有,這里給一個(gè)java的測(cè)試版,加上我的理解注釋:

          /**
           * Created by IntelliJ IDEA.
           * User: zhuangxd
           * Date: 2008-1-7
           * Time: 14:30:44
           
          */
          public class BitSortTest {
              
          private static final int BITSPERWORD = 32;  //整數(shù)位數(shù)
              private static final int SHIFT = 5;
              
          private static final int MASK = 0x1F;  //5位遮蔽 0B11111
              private static final int N = 10000000;
              
          //用int數(shù)組來(lái)模擬位數(shù)組,總計(jì)(1 + N / BITSPERWORD)*BITSPERWORD位,足以容納N
              private static int[] a = new int[(1 + N / BITSPERWORD)];

              
          public static void main(String[] args) {
                  bitsort(
          new int[]{11002100009999456778902});
              }

              
          public static void bitsort(int[] array) {
                  
          for (int i = 0; i < N; i++)
                      clr(i);   
          //位數(shù)組所有位清0
                  for (int i = 0; i < array.length; i++)
                      set(array[i]);  
          //階段2
                  for (int i = 0; i < N; i++)
                      
          if (test(i))
                          System.out.println(i);
              }

              
          //置a[i>>SHIFT]的第(i & MASK)位為1,也就是位數(shù)組的第i位為1
              public static void set(int i) {
                  a[i 
          >> SHIFT] |= (1 << (i & MASK));
              }

              
          //置a[i>>SHIFT]的第(i & MASK)位為0,也就是位數(shù)組的第i位為0
              public static void clr(int i) {
                  a[i 
          >> SHIFT] &= ~(1 << (i & MASK));
              }

              
          //測(cè)試位數(shù)組的第i位是否為1
              public static boolean test(int i) {
                  
          return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
              }
          }



          posted @ 2008-01-07 15:30 dennis 閱讀(3788) | 評(píng)論 (3)編輯 收藏

              提取swf文件元信息、壓縮swf、解壓swf都可以處理,來(lái)自于http://www.brooksandrus.com/blog/category/java/,或者直接這里下載。

          一個(gè)小例子:
                   SWFHeader header = new SWFHeader("G:\\mplayer\\test.swf");
                  System.out.println(
          "signature:   " + header.getSignature());
                  System.out.println(
          "version:     " + header.getVersion());
                  System.out.println(
          "compression: " + header.getCompressionType());
                  System.out.println(
          "size:        " + header.getSize());
                  System.out.println(
          "nbits:       " + header.getNbits());
                  System.out.println(
          "xmax:        " + header.getXmax());
                  System.out.println(
          "ymax:        " + header.getYmax());
                  System.out.println(
          "width:       " + header.getWidth());
                  System.out.println(
          "height:      " + header.getHeight());
                  System.out.println(
          "frameRate:   " + header.getFrameRate());
                  System.out.println(
          "frameCount:  " + header.getFrameCount());
           
          壓縮、解壓縮,需要注意生成的文件將覆蓋原文件:
          //壓縮
          SWFCompressor compressor=new SWFCompressor("G:\\mplayer\\test.swf");
          //解壓縮
          SWFDecompressor decompressor=new SWFDecompressor("G:\\mplayer\\test.swf");




          posted @ 2008-01-04 11:46 dennis 閱讀(3021) | 評(píng)論 (3)編輯 收藏

          update:2008-05-05,POI已經(jīng)可以處理這個(gè)需求:
          package net.rubyeye.test;

          import java.io.FileOutputStream;

          import org.apache.poi.hslf.HSLFSlideShow;
          import org.apache.poi.hslf.model.Picture;
          import org.apache.poi.hslf.usermodel.PictureData;
          import org.apache.poi.hslf.usermodel.SlideShow;

          public class PPTToImageConverter {
              
          public static void main(String[] args) throws Exception {
                  SlideShow ppt 
          = new SlideShow(new HSLFSlideShow("D:/test.ppt"));

                  
          // extract all pictures contained in the presentation
                  PictureData[] pdata = ppt.getPictureData();
                  
          for (int i = 0; i < pdata.length; i++) {
                      PictureData pict 
          = pdata[i];

                      
          // picture data
                      byte[] data = pict.getData();

                      
          int type = pict.getType();
                      String ext;
                      
          switch (type) {
                      
          case Picture.JPEG:
                          ext 
          = ".jpg";
                          
          break;
                      
          case Picture.PNG:
                          ext 
          = ".png";
                          
          break;
                      
          case Picture.WMF:
                          ext 
          = ".wmf";
                          
          break;
                      
          case Picture.EMF:
                          ext 
          = ".emf";
                          
          break;
                      
          case Picture.PICT:
                          ext 
          = ".pict";
                          
          break;
                      
          default:
                          
          continue;
                      }
                      FileOutputStream out 
          = new FileOutputStream("D:/test/pict_" + i + ext);
                      out.write(data);
                      out.close();

                  }
              }
          }

             原文:
             小結(jié)下最近做的東西吧。因?yàn)槭亲鲆粋€(gè)素材管理的東西,因此需要處理各種各樣的素材,音頻、視頻、圖片、pdf、ppt等等。遇到一個(gè)需求就是將PPT轉(zhuǎn)成圖片組,google一下,在java里是可以jcom之類(lèi)的開(kāi)源庫(kù)實(shí)現(xiàn),本質(zhì)上都是通過(guò)jni調(diào)用office的COM接口來(lái)實(shí)現(xiàn)。我們就需要這么一個(gè)小功能,拖這么大個(gè)開(kāi)源庫(kù)進(jìn)來(lái)實(shí)在沒(méi)有必要。最后決定自己寫(xiě)個(gè)動(dòng)態(tài)鏈接庫(kù),通過(guò)jni來(lái)調(diào)用。
              先寫(xiě)工具類(lèi),
          public class PPTUtils {
              
          public PPTUtils() {
              }

              
          public static native void convertPPT2IMG(String pptFileName, String tmpDir);

           
             public static void loadLibrary() {//加載動(dòng)態(tài)庫(kù)
                  String dllFileName = "pptDll";
                  
          try {
                      String OsName 
          = System.getProperty("os.name");
                      
          if (OsName.contains("Windows")) {
                          dllFileName 
          += ".dll";
                      } 
          else {
                          dllFileName 
          += ".so";
                      }
                      
          //加載動(dòng)態(tài)鏈接庫(kù)
                      System.load(dllFileName);
                   
                  }
                  
          catch (Exception e) {
                   
          //   LOG.error("can not load " + dllFileName + ", " + e.getMessage());
                      e.printStackTrace();
                  }
               }
          }

              編譯一下,執(zhí)行javah PPTUtils生成頭文件PPTUtils.h。接下來(lái)用vc寫(xiě)個(gè)動(dòng)態(tài)鏈接庫(kù),記的將MSPPT.OLB(在office安裝目錄下)加入工程,新建一個(gè)ppt2img.cpp:
          #include "stdafx.h"
          #include 
          "PPTUtils.h"
          #include 
          "msppt.h"

          JNIEXPORT 
          void JNICALL Java_com_starnet_dmb_util_PPTUtils_convertPPT2IMG(JNIEnv *env,
                jclass clazz, jstring pptFileName, jstring tmpDir){
             
          //初始化com
              if (CoInitialize( NULL ) == E_INVALIDARG)
              {
                 AfxMessageBox(_T(
          "初始化Com失敗!"));
                 
          return;
              }  
              _Application   app;
              Presentations   prsts;
              _Presentation   prst;
              
          //jstring轉(zhuǎn)成char *
             const char *ppt;
             ppt 
          = env->GetStringUTFChars(pptFileName,0);
             
          const char *tmp;
             tmp
          =env->GetStringUTFChars(tmpDir,0);

             
          if(!app.CreateDispatch(_T("PowerPoint.Application"))){
                AfxMessageBox(_T(
          "初始化PowerPoint失敗!"));
                 
          return;
             }
             prsts   
          =   app.GetPresentations();
             prst   
          =   prsts.Open(_T(ppt),false,false,false);
             prst.SaveAs(_T(tmp),
          17,false);
             app.ReleaseDispatch();
             app.Quit();
             env
          ->ReleaseStringUTFChars(pptFileName,ppt);
             env
          ->ReleaseStringUTFChars(tmpDir,tmp);
             CoUninitialize();
          }

          posted @ 2008-01-04 11:26 dennis 閱讀(4370) | 評(píng)論 (0)編輯 收藏

              挺久沒(méi)動(dòng)筆寫(xiě)blog了,換了新工作比較忙是一個(gè)原因。最近的工作是做一個(gè)素材管理的系統(tǒng),其中有個(gè)要求做視頻預(yù)覽,將用戶上傳的視頻轉(zhuǎn)換并在網(wǎng)頁(yè)上預(yù)覽。在網(wǎng)頁(yè)上看視頻,現(xiàn)在大多數(shù)視頻網(wǎng)站都是采用flv流媒體文件,用flash做的播放器播放,我們也采用了這種方式。流程大概主要:用戶上傳文件->后臺(tái)轉(zhuǎn)換文件成flv格式->flv播放器調(diào)用flv文件。
              轉(zhuǎn)換視頻、音頻文件到flv格式可以使用mencoder或者ffmpeg,我們采用了mencoder,在linux上的安裝參考這里,安裝結(jié)束后記的設(shè)置環(huán)境變量:export LD_LIBRARY_PATH=/usr/local/lib:LD_LIBRARY_PATH
              java調(diào)用的話就是通過(guò)Process:
           Process process = runtime.exec(cmd);

          mencoder轉(zhuǎn)換視頻音頻成flv命令:
          mencoder 源文件 -o 目標(biāo)文件.flv -of lavf    -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=400:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:dia=4:cmp=6:vb_strategy=1 -vf scale=200:-3 -ofps 12 -srate 22050

          取視頻元信息命令(視頻比特率、長(zhǎng)寬等信息):
          mplayer -identify 文件名 -ao null -vo null -frames 0

          切割視頻命令:
          mencoder -ss 開(kāi)始時(shí)間 -oac copy -ovc copy -endpos 終止時(shí)間 文件名 -o 目標(biāo)文件名

              操作flv文件(給視頻打上信息、切割之類(lèi))可以采用flvtool2
             
              需要注意的是通過(guò)java調(diào)用的話,一定要處理標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出,不然進(jìn)程會(huì)掛在那結(jié)束不了,可以開(kāi)個(gè)線程取處理。在網(wǎng)頁(yè)播放的話,可以考慮用這個(gè)播放器,具體參數(shù)看它的說(shuō)明。最后一個(gè)問(wèn)題,IE6的flash控件需要激活,這個(gè)問(wèn)題的解決可以采用swfobject.js
              有興趣的老大們可以考慮自己搭個(gè)“土豆網(wǎng)”,說(shuō)不定哪天拿了風(fēng)投.....浮云

          posted @ 2007-12-19 16:46 dennis 閱讀(7312) | 評(píng)論 (5)編輯 收藏

          僅列出標(biāo)題
          共56頁(yè): First 上一頁(yè) 30 31 32 33 34 35 36 37 38 下一頁(yè) Last 
          主站蜘蛛池模板: 昌宁县| 屏东市| 白银市| 介休市| 南城县| 定襄县| 得荣县| 嵊泗县| 稻城县| 盖州市| 庆城县| 乐安县| 府谷县| 旬阳县| 开封市| 临武县| 东安县| 榆树市| 慈溪市| 长泰县| 芜湖县| 海淀区| 铜川市| 宜章县| 万荣县| 湾仔区| 永善县| 泰安市| 如皋市| 沧州市| 思南县| 白山市| 堆龙德庆县| 宝鸡市| 五常市| 崇左市| 新竹县| 博乐市| 呼玛县| 南阳市| 罗江县|