Java使用StringBuilder索引越界 : String index out of range: -1

问题遇到的现象和发生背景
   因为项目需求,需要将一个长字符串进行切割来向硬件按帧通讯,字符串长度为16进制的38400字节,也就是76800字符,这已经远远超出了java String常量的限制65534,遂采用读写文件的形式进行处理;
   现在思路是通过读取出来的Arraylist循环创建了3Stringbuilder,长度分别为36360,36360,4040,在客户端里使用For循环来通过substring方法依次获取长度为2020,1010字节的数据,加上自定义传输协议的帧头帧尾拼装成1K大小的数据帧来进行TCP SOCKET发送.
   但在获取第27帧的时候就会出现问题,报索引越界的错误.根据代码来看入参,本身的3StringBuilder获取出来打印都是正常的,检查不出问题所在,非常疑惑,下面贴上相关代码,其中frameNum为数据帧帧数,是通过客户端的for循环来获取的,其值为1~39 :
问题相关代码
String photoFrame = "";
String dbTmp = "";
String dbPlus = "";
String s = Integer.toString(frameNum);
        if (frameNum == 1) {
            dbTmp = stringBuilder1.substring(0, 2020);
            dbPlus = "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp;
            photoFrame = "XX" + "XX" + str2HexStr(CCUCode) + "XX" + "XX" + "XX" + "XX" + "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp + getSub2Hex(dbPlus) + getXor2Hex(dbPlus) + "XX";
        } else if (1 < frameNum && frameNum < 19) {
            dbTmp = stringBuilder1.substring(2020 * (frameNum - 1), 2020 * frameNum);
            dbPlus = "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp;
            photoFrame = "XX" + "XX" + str2HexStr(CCUCode) + "XX" + "XX" + "XX" + "XX" + "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp + getSub2Hex(dbPlus) + getXor2Hex(dbPlus) + "XX";
        } else if (18 < frameNum && frameNum < 37) {
            dbTmp = stringBuilder2.substring(2020 * (frameNum - 19), 2020 * (frameNum - 18));
            dbPlus = "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp;
            photoFrame = "XX" + "XX" + str2HexStr(CCUCode) + "XX" + "XX" + "XX" + "XX"+ "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp + getSub2Hex(dbPlus) + getXor2Hex(dbPlus) + "XX";
        } else if (36 < frameNum && frameNum < 39) {
            dbTmp = stringBuilder3.substring(2020 * (frameNum - 37), 2020 * (frameNum - 36));
            dbPlus = "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp;
            photoFrame = "XX" + "XX" + str2HexStr(CCUCode) + "XX" + "XX" + "XX" + "XX" + "XX"+ "XX" + str2HexStr(s) + "XX" + dbTmp + getSub2Hex(dbPlus) + getXor2Hex(dbPlus) + "XX";
        } else if (frameNum == 39) {
            dbTmp = stringBuilder3.substring(stringBuilder3.length() - 40);
            dbPlus = "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp;
            photoFrame = "XX" + "XX" + str2HexStr(CCUCode) + "XX" + "XX" + "XX" + "XX" + "XX" + "XX" + str2HexStr(s) + "XX" + dbTmp + getSub2Hex(dbPlus) + getXor2Hex(dbPlus) + "XX";
        }
        return photoFrame.toLowerCase().trim();

运行结果及报错内容
Exception in thread "main" java.lang.RuntimeException: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at com.XX.XX.common.utils.Client.main(Client.java:108)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1927)
    at com.XX.XX.common.utils.Client.getXor2Hex(Client.java:298)
    at com.XX.XX.common.utils.Client.arr2String(Client.java:134)
    at com.XX.XX.common.utils.Client.main(Client.java:64)

我的解答思路和尝试过的方法
之前考虑过可能是重复创建StringBuilder引起的内存溢出,所以把需要重复生成的东西都提取出来,现在main程序就是起到一个截取拼装的作用.
也考虑过加大传送缓存区的方案,但也并未奏效.
我想要达到的结果
能够正常切割字符串并完成拼装,希望大佬们不吝赐教,谢谢!

访问的索引为-1,导致的异常。
报错的地方,加点日志信息。

看来这个问题还没解决哈,好吧。
首先针对你说的第27帧的问题,我想你可以单独针对第27帧进行debug中查看下,这个一帧的数据本身是否存在问题,如果存在问题就可以去找到返回数据方再生成数据时的问题了。
其次针对你说的关于String常量的限制65534的问题,这个是由于你是直接把获取到的字符串进行如此 String text = “获取到的值” 的赋值,所以会有如此的限制,要想解决这个限制可以按如下方式来处理:
1、获取到的字符串直接存储为 文件,比如: text.txt
2、读取该文件数据到 String 对象中,代码如下:

    //读取文件到byte[]
    private static byte[] getFileBytes(String file) {
        try {
            File f = new File(file);
            int length = (int) f.length();
            byte[] data = new byte[length];
            new FileInputStream(f).read(data);
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

 // 数据读取到String

String bigStr = new String(getFileBytes("/home/xxx/text.txt"));
//然后就可以直接处理bigStr 了,省区了你要分段处理的麻烦。