0

こんにちは、誰かがこの問題を解決するのを手伝ってくれることを願っています..

私の観点からは、ここにコードセクションがあってはならないのに、なぜこのランタイムエラーが発生するのか興味があります:

// Send Message to the Message Log 

public static void SendMesg() 
   {   
      String mesg_str = message_data.toString() ;        
      int msgstr_len = mesg_str.length();            // determine actual message length
      int array_len  = mesgwork.length ;     // determine actual mesgwork array length
      dt_stamp = getDateTime() ; 
      System.out.println(dt_stamp) ; 
      System.out.println( " LU62XnsCvr Diagnostic:");
      System.out.println(" LU62XCI0100: Method = SendMesg") ; 
      System.out.println(" Message to be sent: " ) ;
      System.out.println(mesg_str) ;
      System.out.println("mesg_str Length=") ;
      System.out.println(msgstr_len) ; 
      System.out.println("Derived mesgwork Length=") ;
      System.out.println(array_len) ; 
      System.out.println("Class Var MGBuffer length value: ") ;
      System.out.println(MGBUFLN) ; 
      System.out.println("Buffer Offset Value=") ;
      System.out.println(bufroffset) ;
      System.out.println( " LU62XnsCvr End Diagnostic") ;

      mesgwork = mesg_str.getBytes() ;        //Convert msg string to byte array 
      mesg_bufr.put( mesgwork, bufroffset, MGBUFLN ) ;// <= error occurs here  
      pgm_cntl = WRITE_MESG ;
      FileControl() ; 
      if (pgm_cntl == WRITE_ERROR) 
        { 
         sys_return = pgm_cntl ;
         SysEnd( sys_return ) ;
        }
      mesgcount = mesgcount + 1 ;                    // increment the message counter
      mesg_bufr.clear() ; 
      message_data.append("                ")  ;     // 16 bytes of blanks
      clearByteArray( mesgwork, MGBUFLN ) ;

   }  // End of Send Message log write sub-routine 

プログラムを実行すると、次のように表示されます。

2011.05.12 10:48:07    
LU62XnsCvr Diagnostic:  

 LU62XCI0100: Method = SendMesg
 Message to be sent:2011.05.12 10:48:07 LU62XCE0313: CPIC Return Code =1 CM Alloc  ConversationID=[B@201d201d  

mesg_str Length=89  

Derived mesgwork Length=192  

Class Var MGBuffer length value:192  

Buffer Offset Value=0  

 LU62XnsCvr End Diagnostic  


Exception in thread "main" java.lang.IndexOutOfBoundsException
        at java.nio.Buffer.checkBounds(Buffer.java:543)
        at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:177)
        at APPC_LU62.Runtime.LU62XnsCvr.SendMesg(LU62XnsCvr.java:652)
        at APPC_LU62.Runtime.LU62XnsCvr.StartConvrs(LU62XnsCvr.java:517)
        at APPC_LU62.Runtime.LU62XnsCvr.ProcessRqsts(LU62XnsCvr.java:398)
        at APPC_LU62.Runtime.LU62XnsCvr.main(LU62XnsCvr.java:357)

これは、LU62XnsCvr クラス内での参照の前に宣言された整数変数 MGBUFLN です。

final static int MGBUFLN   = 192 ;    //Message Buffer Length 

これは、LU62XnsCvr クラスのメンバー変数として宣言された「ソース」として使用されるバイト配列です...

static byte[] mesgwork = new byte[MGBUFLN] ;

これは、Oracle Java Doc Web サイトからコピーしたものです。どのくらい最新かは正確にはわかりませんが、
Java 6 としてマークされており、Java 1.6 を使用する IBM の SDK を実行しています。

public ByteBuffer put(byte[] src, int オフセット, int 長さ)

相対一括プット方式 (オプション操作)。このメソッドは、指定されたソース配列からこのバッファーにバイトを転送します。配列からコピーするバイト数が、このバッファーに残っているバイト数よりも多い場合 (つまり、長さ > 残り ()) の場合、バイトは転送されず、BufferOverflowException がスローされます。それ以外の場合、このメソッドは、配列内の指定されたオフセットおよびこのバッファーの現在位置から開始して、指定された配列からこのバッファーに length バイトをコピーします。次に、このバッファーの位置が長さだけインクリメントされます。つまり、この形式のメソッドの呼び出しはdst.put(src, off, len)、ループとまったく同じ効果があります。

 for (int i = off; i < off + len; i++)
     dst.put(a[i]);

ただし、最初にこのバッファーに十分なスペースがあることを確認し、はるかに効率的である可能性があります。

パラメーター:

  • src - バイトが読み取られる配列
  • offset - 読み取られる最初のバイトの配列内のオフセット。負でなく、array.length 以下でなければなりません
  • length - 指定された配列から読み取るバイト数。負ではなく、array.length - オフセット以下でなければなりません

戻り値: このバッファ

スロー:

  • BufferOverflowException - このバッファーに十分なスペースがない場合
  • IndexOutOfBoundsException - オフセットおよび長さパラメーターの前提条件が満たされていない場合
  • ReadOnlyBufferException - このバッファが読み取り専用の場合

私は次のステートメントに少し関心があります。

それ以外の場合、このメソッドは、配列内の指定されたオフセットおよびこのバッファーの現在位置から開始して、指定された配列からこのバッファーに length バイトをコピーします。次に、このバッファーの位置が長さだけインクリメントされます。

その後:

ただし、最初にこのバッファーに十分なスペースがあることを確認し、はるかに効率的である可能性があります。

// * 私の追加コメント * //

ここで、192バイトのバッファを完全に「埋める」必要があります(インデックスは0〜191の範囲です)したがって、ドキュメントに記載されているように、バッファは長さ (この場合は192バイト)
だけ「増加」します

次に、「ロジック」がインデックスに192バイトを追加し
、見よ...インデックスの範囲外にあることを暗示しているように私には思えます...

これについて誰かの意見をいただければ幸いです。
コメントや提案を待っています...

ありがとう

4

2 に答える 2

0

mesgworkより少ない要素を含む配列ですbufroffset + MGBUFLN

配列をsize=で初期化するので、これが機能するためには、常に0でなければならないMGBULFNと思います。bufferoffset

それとは別に、-MGBULFNは定数のかなり不可解な名前です。名前を変更することを検討してください。

于 2011-05-12T23:32:14.573 に答える
0

ラインで

mesg_bufr.put( mesgwork, bufroffset, MGBUFLN ) ;

MGBUFLN (つまり 192) バイトを mesgwork バイト配列からバッファに転送しようとしています。しかし、mesgwork 配列には 89 バイトしかないため、範囲外の例外が発生します。

これを試して:

mesg_bufr.put( mesgwork, bufroffset, mesgwork.length ) ;
于 2011-05-12T23:44:31.177 に答える