问题
Converts bytearray data received through communication into String.
If the byte array is long (ex 355), the end is truncated.
Same goes for utf-8, utf-16 etc.
fun getString(content:ByteArray, length: Int): String? {
var str: String? = null
try {
str = String(content, 0, length, Charset.forName("euc-kr"))
i("Test::getString str : " + str)
} catch (e: java.lang.Exception) {
i("Test::getString ERR ")
error("Charset exception", DlgAprList::class.java)
}
return str
}
Occurs when it exceeds 355 bytes, if you look at the image of the attached link, it was 389 bytes and you can see that truncation occurred.
In other functions, use the getString function like this.
var str : String? = getString(data, data.size)
var info: Array<String> = str!!.split(";").toTypedArray()
for (i in 0 until info.size - 1) {
var temp = info[i].split("-".toRegex()).toTypedArray()
var name = temp[0]
var desc = temp[1]
var final = name +"-"+ desc
var finalresult : DlgAprInfo = DlgAprInfo(name,desc)
i("Test::parseAndReplace temp size : " + info.size + " temp " + i +" : " + finalresult.name + "-"+ finalresult.desc)
//listnew.add(final)
list.add(finalresult) // testver
}
I've attached the code from the first receiving point
_networkReader = BufferedInputStream(BufferedInputStream(_socket!!.getInputStream()))
var bytesRead = _networkReader!!.read(buffer, 0, Companion.BUFFER_LEN)
if (bytesRead >= 0) {
if (!_connect) NotifyConnect()
var command = buffer[4]
var content: ByteArray? = null
var length : Int = 0
var index = 0
while (index + 3 < bytesRead) {
var contentlength: Int = ((buffer[index] and 0xff.toByte()).toInt() shl 24) + ((buffer[index + 1] and 0xff.toByte()).toInt() shl 16) + ((buffer[index + 2] and 0xff.toByte()).toInt() shl 8) + ((buffer[index + 3] and 0xff.toByte()).toInt() shl 0)
var cmd = buffer[index + 4]
if (bytesRead > Companion.COMMAND_LEN) {
content = ByteArray(bytesRead - index - Companion.COMMAND_LEN - 4)
length = content.size
System.arraycopy(buffer, index + 5, content, 0, contentlength)
}
processPacket(cmd, content, contentlength)
}
}
processPacket Function
private fun processPacket(command: Byte, content: ByteArray?, length: Int) {
try {
if (content != null) {
LogUtil.i("StandElin 1-1 " + "Command 0x" + Integer.toHexString(command.toInt()) + " "
+ String(content, 0, length, CHARSET))
} else {
LogUtil.i("StandElin 1-2" + "Command 0x" + Integer.toHexString(command.toInt()))
}
LogUtil.i("StandElin 2 FinalCommand : 0x" + Integer.toHexString(command.toInt()))
var message: Message? = null
var parsed: Any? = null
DlgAprList.instance?.parseAndReplace(content)
The first code attached to the top is a function included in the DlgAprList class
回答1:
I created a repo that you can run your use-cases against with tests: GitHub
There are several possible issues:
- Can
Log.i
cause any troubles? - Check the initial encoding you encode with:
val str = "My long string"
val byteArray = str.toByteArray(Charset.forName("utf-8"))
- Check the encoding you decode with. In your code, I see that
euc-kr
encoding is hard-coded. It means that if you encoded with utf-8 and decode with a different one, the code will fail.
来源:https://stackoverflow.com/questions/65712797/kotlin-converts-bytearray-to-string-data-crash