Kotlin应用突破65535字节限制:USB大PNG加载崩溃解决
解决方案:突破64KB限制读取USB图片数据并解码
首先明确:Android的ByteArray本身没有64KB(65535字节)的限制,你遇到的崩溃并非数组大小导致,而是InputStream未完整读取数据,后续BitmapFactory.decodeByteArray解析不完整的PNG数据时引发崩溃。下面是针对性的修复方案:
1. 修复InputStream读取逻辑
InputStream.read()方法无法保证一次性读取指定长度的字节,必须通过循环读取确保数据完整:
// IS is the InputStream // 读取图片大小(32位无符号整数) val sizeBuffer = ByteArray(4) IS.read(sizeBuffer, 0, 4) val siz = ByteBuffer.wrap(sizeBuffer).order(ByteOrder.LITTLE_ENDIAN).getInt() // 初始化对应大小的字节数组 val imageBytes = ByteArray(siz) var totalRead = 0 // 循环读取直到获取完整数据 while (totalRead < siz) { val readCount = IS.read(imageBytes, totalRead, siz - totalRead) if (readCount == -1) { // 数据流提前结束,抛出异常或做容错处理 throw IOException("Stream ended before reading all image data") } totalRead += readCount } // 解码Bitmap val bt = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
2. 更高效的方案:直接使用decodeStream解码
你之前尝试的BitmapFactory.decodeStream完全适用于持续数据流,只需确保流的指针位于图片数据的起始位置(读完4字节大小后,流指针已经正确指向图片数据)。这种方式无需将完整图片数据加载到内存,内存占用更低:
// IS is the InputStream // 读取图片大小(可选,若不需要验证可跳过) val sizeBuffer = ByteArray(4) IS.read(sizeBuffer, 0, 4) val siz = ByteBuffer.wrap(sizeBuffer).order(ByteOrder.LITTLE_ENDIAN).getInt() // 直接从流解码Bitmap val bt = BitmapFactory.decodeStream(IS)
崩溃原因说明
测试中65534字节正常、65535字节崩溃,是因为当数据量较小时,InputStream.read()大概率一次性读完;但数据量超过64KB时,单次读取无法获取完整数据,导致imageBytes中存在无效数据,decodeByteArray解析PNG时因数据不完整崩溃。
内容的提问来源于stack exchange,提问作者user22437922
相关产品推荐
相关产品推荐

