2016-03-23 25 views
1

大きなテキストファイルを表示する必要があります。電子書籍としてスクロールせずにテキストを表示します。私はそのページの長いテキストを壊すことができますが、時間がかかりすぎます。たとえば、次のコードでは1.4 MBのテキストを約10-15秒間処理します。Androidの長いテキストページ区切り

public void split(TextPaint textPaint, String filepath,Context context) { 
     int pages = 0; 
     File file = new File(filepath); 
     char[] bufferChar = new char[1024]; 
     String uncompletedtext=""; 
     //How lines we can show 
     int maxLinesOnpage = 0; 
     StaticLayout staticLayout = new StaticLayout(
       context.getString(R.string.lorem_ipsum), 
       textPaint, 
       pageWidth, 
       Layout.Alignment.ALIGN_NORMAL, 
       lineSpacingMultiplier, 
       lineSpacingExtra, 
       false 
     ); 
     int startLineTop = staticLayout.getLineTop(0); 
     int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight); 
     int endLineBottom = staticLayout.getLineBottom(endLine); 
     if (endLineBottom > startLineTop + pageHeight) { 
      maxLinesOnpage = endLine - 1; 
     } else { 
      maxLinesOnpage = endLine; 

     } 


     //let's paginate 
try { 
      BufferedReader buffer = new BufferedReader(new FileReader(file)); 
      while (buffer.read(bufferChar)>=0) { 
       uncompletedtext += new String(bufferChar); 
       boolean allcomplete = false; 


        staticLayout = new StaticLayout(
          uncompletedtext, 
          textPaint, 
          pageWidth, 
          Layout.Alignment.ALIGN_NORMAL, 
          lineSpacingMultiplier, 
          lineSpacingExtra, 
          false 
        ); 
        staticLayout.getLineCount(); 
        int curTextPages= (int) Math.floor(staticLayout.getLineCount()/maxLinesOnpage); 
        uncompletedtext=uncompletedtext.substring(staticLayout.getLineEnd(curTextPages)); 
        pages+=curTextPages; 
        Log.e("PAGES","" + pages); 



      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     Log.e("FILE READED FULLY!!", "READ COMPLETE!!!!!!!!!!!!!!!!"); 




    } 

これは長すぎます。私は、FBReaderやСoolReaderなどのアプリケーションが大きなファイル(9 MB以上)を即座に処理する方法を理解できません。 私はアプリケーションのソースを見ましたが、すぐに回答を見つけるには機能が多すぎます。 私は本当に助けとヒントが必要です。ありがとう。

+0

う[アンドロイドでページの区切りテキスト](http://stackoverflow.com/questions/31837840/paginating-text-in-android)を助けます?.. 。 – Onik

+0

それは素晴らしい解決策ですが、大きなテキストのためではありません。 – SlyBeaver

+0

'while(buffer.read(bufferChar)> = 0)'ループの繰り返しごとに 'StaticLayout'の新しいインスタンスを作成します。これは高価な操作であり、パフォーマンスの問題を引き起こす可能性があります。 – Onik

答えて

0

ありがとうございます!私は解決策を見つける!エレガントな非常に高速なコード(10Mbの〜600ミリ秒)ではない

public void split(TextPaint textPaint, String filepath,Context context) { 
     File file = new File(filepath); 
     char[] bufferChar = new char[512]; 
     //How lines on page 
     int maxLinesOnpage = 0; 
     int symbolsOnLine = 0; 
     StaticLayout staticLayout = new StaticLayout(
       context.getString(R.string.lorem_ipsum),//short text with 100 lines (\r\n\r\n\r\n\r\n\r\n\r\n) 
       textPaint, //MONOSPACE!!! 
       pageWidth, 
       Layout.Alignment.ALIGN_NORMAL, 
       lineSpacingMultiplier, 
       lineSpacingExtra, 
       false 
     ); 
     int startLineTop = staticLayout.getLineTop(0); 
     int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight); 
     int endLineBottom = staticLayout.getLineBottom(endLine); 
     if (endLineBottom > startLineTop + pageHeight) { 
      maxLinesOnpage = endLine - 1; 
     } else { 
      maxLinesOnpage = endLine; 
     } 
     symbolsOnLine = staticLayout.getLineEnd(0); 

     try { 
      RandomAccessFile rac = new RandomAccessFile(file, "r"); 
      byte[] buffer = new byte[2048]; 
      int wordLen = 0; //Length of word in symbols 
      int wordInBytes = 0; //Lenght of word 
      int startLinePos = 0; //Start first line position 
      int lineWidth = 0; //Current line length 
      int totalLines =0; //Total lines on current page 
      Log.e("Start pagination", "" + totalLines); 
      long timeout= System.currentTimeMillis(); 
      int buflen=0; //buffer size 
      int totalReadedBytes = 0; //Total bytes readed 
      byte skipBytes = 0; 
      while ((buflen=rac.read(buffer))!=-1){ 
       for (int i=0;i<buflen;i++) { 
        totalReadedBytes++; 
        wordInBytes++; 
        if (skipBytes==0){ //Bytes on one symbol 
         if (unsignedToBytes(buffer[i])>=192){skipBytes=2;} 
         if (unsignedToBytes(buffer[i])>=224){skipBytes=3;} 
         if (unsignedToBytes(buffer[i])>=240){skipBytes=4;} 
         if (unsignedToBytes(buffer[i])>=248){skipBytes=5;} 
         if (unsignedToBytes(buffer[i])>=252){skipBytes=6;} 
        } 
        //Full bytes on symbol or not 
        if (skipBytes>0){ 
         skipBytes--; 
         if (skipBytes>0){continue;} 
        } 

        if (buffer[i] == 13) {//We have a \r symbol. Ignore. 
         continue; 
        } 



        if (buffer[i]==10){//New line symbol 
         if (lineWidth + wordLen>symbolsOnLine){ 
          totalLines++; 
          if (totalLines > maxLinesOnpage) { 
           int[] pgsbytes = {startLinePos, totalReadedBytes}; 
           pages.add(pgsbytes); 
           startLinePos = totalReadedBytes ; 
           totalLines = 0; 
          } 
         } 
         wordLen=0; 
         wordInBytes=0; 
         totalLines++; 
         lineWidth=0; 
         if (totalLines>maxLinesOnpage){ 
          int[] pgsbytes = {startLinePos, totalReadedBytes-1}; 
          pages.add(pgsbytes); 
          startLinePos = totalReadedBytes-1; 
          totalLines=0; 
         } 
        } 

        if (buffer[i]==32){//Space symbol 
         if (lineWidth + wordLen+1<=symbolsOnLine){//Word fits in line 
          lineWidth+=wordLen + 1; 
          wordLen=0; 
          if (lineWidth==symbolsOnLine){ 
           totalLines++; 
           if (totalLines > maxLinesOnpage) { 
            int[] pgsbytes = {startLinePos, totalReadedBytes}; 
            pages.add(pgsbytes); 
            startLinePos = totalReadedBytes ; 
            totalLines = 0; 
           } 
           lineWidth = 0; 
           wordLen = 0; 
           wordInBytes=0; 
          } 
         } else { 
          if (lineWidth + wordLen==symbolsOnLine){ 
           totalLines++; 
           if (totalLines > maxLinesOnpage) { 
            int[] pgsbytes = {startLinePos, totalReadedBytes}; 
            pages.add(pgsbytes); 
            startLinePos = totalReadedBytes ; 
            totalLines = 0; 
           } 
           lineWidth = 0; 
           wordLen = 0; 
           wordInBytes=0; 
          } else { 
           totalLines++; 
           if (totalLines > maxLinesOnpage) { 
            int[] pgsbytes = {startLinePos, totalReadedBytes - 1 - wordInBytes}; 
            pages.add(pgsbytes); 
            startLinePos = totalReadedBytes - 1; 
            totalLines = 0; 
           } 
           lineWidth = wordLen + 1; 
           wordLen = 0; 
           wordInBytes=0; 
          } 
         } 
        } 

        if (buffer[i]!=32&&buffer[i]!=10&&buffer[i]!=13){wordLen++; } 
        if (wordLen==symbolsOnLine){ 
         totalLines++; 
         if (totalLines>maxLinesOnpage){ 
          int[] pgsbytes = {startLinePos, totalReadedBytes-1 - wordInBytes}; 
          pages.add(pgsbytes); 
          startLinePos = totalReadedBytes-1; 
          totalLines=0; 
         } 
         lineWidth=0; 
         wordLen=0; 
         wordInBytes=0; 
        } 
       } 

      } 
      rac.close(); 
      timeout = System.currentTimeMillis() - timeout; 
      Log.e("TOTAL Time", " time " + timeout + "ms"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     Log.e("FILE READED FULLY!!", "READ COMPLETE!!!!!!!!!!!!!!!!"); 
    } 
+2

私はあなたのような問題があります。しかし、私はあなたの解決策を理解していません。ページングテキストの完全なコードを私に教えてもらえますか?私はあなたのコードを私のテキストファイル(〜6MB)で試してみると6秒かかる。 –