【问题标题】:ByteArrayInputStream read() method throws IndexOutOfBoundsExceptionByteArrayInputStream read() 方法抛出 IndexOutOfBoundsException
【发布时间】:2012-02-10 07:36:34
【问题描述】:

对于这里有经验的人来说,这应该是一个简单的问题。我是 Java 初学者,所以我已经尝试解决这个问题几个小时了。 我正在通过实际工作学习Java,我已经阅读了有关数组和内存分配的内容,但可能我仍然不明白。

我正在编写这种方法,它基本上采用源文本,例如“bla bla bla search entry bla bla bla”,并应通过返回类似“bla bla bla {font=red}search entry{/font} bla bla bla”的字符串来突出显示搜索条目。 如果源文本是英文的,没有问题,函数的前半部分(我没有包含它)运行良好。 但是如果源文本是双字节编码的,我必须使用 ByteArrayInputStream 和 ByteArrayOutputStream 来做同样的事情。

代码如下:

            sDebug=new String(retVal, "UTF-8");
            final String sHtml1="<font color='green'><b>";
            final String sHtml2="</b></font>";


            ByteArrayOutputStream baOut=new ByteArrayOutputStream();
            //retVal contains source text
            ByteArrayInputStream baIn=new ByteArrayInputStream(retVal); );

            try
            {
            //posB - where search entry begins in retVal
            posB=Integer.valueOf(srchArray[j+2]);
            //posE - where search entry ends in retVal
            posE=posB+Integer.valueOf(srchArray[j+3]);
            byte[] buffer=new byte[posB];
            //read from beginning till posB
            baIn.read(buffer, 0, posB);
            sDebug=new String(buffer, "UTF-8");

            baOut.write(buffer);
            baOut.write(sHtml1.getBytes("UTF-8") );

            sDebug=new String(baOut.toByteArray(), "UTF-8");

            buffer=new byte[posE-posB];

            //*************************************************
            //*********THIS IS WHERE IT THROWS EXCEPTION:******
            baIn.read(buffer, posB, posE-posB);
            baOut.write(buffer);
            sDebug=new String(baOut.toByteArray(), "UTF-8");
            baOut.write(sHtml2.getBytes("UTF-8"));
            sDebug=new String(baOut.toByteArray(), "UTF-8");
            buffer=new byte[retVal.length-posE];
            baIn.read(buffer, posE, retVal.length-posE);
            baOut.write(buffer);
            sDebug=new String(baOut.toByteArray(), "UTF-8");

            retVal=baOut.toByteArray();
            sDebug=new String(baOut.toByteArray(), "UTF-8");
            //sDebug=baOut.toString("UTF-8");
            }
            catch(Exception e)
            {
                 String err="Error: " + e.getMessage();
                 Toast.makeText(Central.context, err, Toast.LENGTH_LONG).show();
            }

【问题讨论】:

  • 问题似乎出在这几行 posB=Integer.valueOf(srchArray[j+2]);和 posE=posB+Integer.valueOf(srchArray[j+3]); .看来您正在访问不存在的 srchArray 元素。
  • 异常发生在哪一行?
  • 请重新访问您以前的问题并检查您是否可以接受一些答案。这将鼓励人们提供更多帮助。
  • 我重新审视了我的旧问题。感谢那。我没有注意到每个答案旁边的灰色大勾号,现在我应该没事了。
  • 2 迈克。这些行很好,在此之后的下一行发生异常 //*********这是抛出异常的地方:******

标签: java android bytearrayinputstream


【解决方案1】:

如果这一行:

   baIn.read(buffer, posB, posE-posB);

抛出一个边界异常,它告诉你你的索引计算有误。换句话说,索引posBposE - 1 并不都在buffer 内。


对于这里有经验的人来说,这应该是一个简单的问题。

你会感到惊讶。这很难,因为:

  • 您的代码凌乱且难以阅读,
  • 您的代码逻辑很丑陋,并且充满了莫名其妙的硬连线常量,
  • 您的代码不完整并且包含明显的编译错误,并且
  • 您对您正在尝试做的事情的描述很难阅读/理解

简而言之,这太可怕了。

所以作为一个有经验的程序员,我建议你把它扔掉,然后从头开始重写。 (如果我必须对它进行代码审查,我会直接拒绝它,因为它明显无法维护,无论它是否“有效”。)

如果实在难以忍受,你需要学习使用调试器。

最后一条建议是,Java 中的字节打击文本数据太疯狂了。将其视为基于字符的,您可以使用一整套功能强大且(如果使用合理的话)高效的类库,从 String / StringBuilder 开始,一直到扫描仪、格式化程序和正则表达式。

【讨论】:

  • 谢谢斯蒂芬。我知道这很糟糕。我只是想让它做我需要的。我不将其视为字符串的原因是我有 fts sqlite 搜索,它返回包含文本 sqlite.org/fts3.html#section_4_1 中搜索条目位置的偏移字符串。现在我需要操作文本以便大纲搜索条目。我不得不使用 ByteArray 流类,因为偏移量以字节为单位,但字符串中的文本使用 2 个字节和 1 个字节作为空间编码,这使得这些偏移量无法与 String 类一起使用
【解决方案2】:

问题在于,而不是

baIn.read(buffer, posB, posE-posB);

我应该用过

baIn.read(buffer, 0, posE-posB); 

看起来第二个参数必须始终为 0,尽管 doc 中写的是什么。

【讨论】:

    猜你喜欢
    • 2016-04-04
    • 2023-03-28
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 2021-12-20
    • 2018-07-31
    相关资源
    最近更新 更多