问题遇到的现象和发生背景
因为项目需求,需要将一个长字符串进行切割来向硬件按帧通讯,字符串长度为16进制的38400字节,也就是76800字符,这已经远远超出了java String常量的限制65534,遂采用读写文件的形式进行处理;
现在思路是通过读取出来的Arraylist循环创建了3个Stringbuilder,长度分别为36360,36360,4040,在客户端里使用For循环来通过substring方法依次获取长度为2020,即1010字节的数据,加上自定义传输协议的帧头帧尾拼装成1K大小的数据帧来进行TCP SOCKET发送.
但在获取第27帧的时候就会出现问题,报索引越界的错误.根据代码来看入参,本身的3个StringBuilder获取出来打印都是正常的,检查不出问题所在,非常疑惑,下面贴上相关代码,其中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程序就是起到一个截取拼装的作用.
也考虑过加大传送缓存区的方案,但也并未奏效.
我想要达到的结果
能够正常切割字符串并完成拼装,希望大佬们不吝赐教,谢谢!