IndexOutOfBoundsException, генерируемый java.nio bytebuffer.put (byte [] arsrc, int offset, int length) - PullRequest
0 голосов
/ 13 мая 2011

Привет всем. Я надеюсь, что кто-то может помочь мне решить эту проблему ..

Мне интересно, почему я получаю эту ошибку времени выполнения, когда, с моей точки зрения, я не должен вот этот раздел кода:

// 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)

здесь целочисленная переменная MGBUFLN, объявленная до любой ссылки на нее в классе LU62XnsCvr

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

вот байтовый массив, который используется в качестве «источника», объявленного как переменная-член класса LU62XnsCvr ...

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

Это я скопировал с веб-сайта Oracle Java Doc;не знаю точно, насколько он актуален,
, но он помечен как java 6, и я использую SDK IBM, который использует java 1.6

public ByteBuffer put (byte [] src, intсмещение, длина int)

Метод относительной насыпной массы (необязательная операция).Этот метод передает байты в этот буфер из заданного исходного массива.Если из массива нужно скопировать больше байтов, чем осталось в этом буфере, то есть если length> Осталось (), то байты не передаются и генерируется исключение BufferOverflowException.В противном случае этот метод копирует байты длины из данного массива в этот буфер, начиная с заданного смещения в массиве и с текущей позиции этого буфера.Положение этого буфера затем увеличивается на длину.Другими словами, вызов этого метода в форме dst.put(src, off, len) имеет точно такой же эффект, что и цикл

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

, за исключением того, что он сначала проверяет, достаточно ли места в этом буфере и потенциально многоболее эффективный.

Параметры:

  • src - Массив, из которого должны быть прочитаны байты
  • смещение - Смещение в массиве первого байта, который будетчитать;должно быть неотрицательным и не больше, чем array.length
  • length - количество байтов, которые будут считаны из данного массива;должно быть неотрицательным и не больше array.length - offset

Возвращает: Этот буфер

Броски:

  • BufferOverflowException - если недостаточнопробел в этом буфере
  • IndexOutOfBoundsException - если предварительные условия для параметров смещения и длины не сохраняются
  • ReadOnlyBufferException - Если этот буфер только для чтения

Я немного обеспокоен утверждениями:

В противном случае этот метод копирует байты длины из данного массива в этот буфер, начиная с заданного смещения в массиве и с текущей позиции этогобуфер.Положение этого буфера затем увеличивается на длину.

, а затем:

за исключением того, что сначала он проверяет, достаточно ли в этом буфере пространства и потенциально многоболее эффективно.

// * мои дополнительные комментарии * //

Теперь я хочу полностью «заполнить» 192-байтовый буфер (поэтому индекс варьируется от0 - 191)
Таким образом, если, как указано в документе, буфер «увеличивается» на длину
(в данном случае 192 байта)

, то это, как мне кажется, подразумевает"логика" добавит 192 байта к индексу и
минимум, и вот ... мы вышли за пределы индекса ...

Буду очень признателен за мнение каждого по этому поводу.
Жду ваших комментариев и / или предложений ...

Спасибо

Парень

Ответы [ 2 ]

0 голосов
/ 13 мая 2011

В строке

mesg_bufr.put( mesgwork, bufroffset, MGBUFLN ) ;

вы пытаетесь передать байты MGBUFLN (т.е. 192) из ​​байтового массива mesgwork в буфер.Но в вашем массиве сообщений содержится всего 89 байт, поэтому вы получаете исключение вне границ.

попробуйте это:

mesg_bufr.put( mesgwork, bufroffset, mesgwork.length ) ;
0 голосов
/ 13 мая 2011

mesgwork - это массив, который содержит меньше элементов, чем bufroffset + MGBUFLN

Так как вы инициализируете свой массив с размером = MGBULFN, тогда я бы предположил, что ваш bufferoffset должен всегда быть 0, чтобы это работало.

Кроме того - MGBULFN - довольно загадочное имя для константы. Подумайте о переименовании.

...