相同代码与数据却输出不同结果?Android写入dat文件代码疑问
问题分析与解答
一、相同代码&数据却输出不同的原因
这种情况在开发中真的挺常见的,大概率是这些隐藏因素在搞鬼:
- 环境差异:你是在OnePlus2上运行,有没有和其他测试环境(比如模拟器、其他机型)对比过?不同Android版本的API实现可能有细微差别,甚至系统的默认编码、文件系统权限都可能影响结果。
- 状态残留问题:如果你的代码依赖了全局变量、单例对象的状态,或者之前运行的残留数据没清理,就会导致每次运行的初始状态不一样,输出自然不同。
- 并发/线程问题:如果这段代码是在多线程环境下跑的(比如Android的AsyncTask、线程池),没有做好同步的话,可能会出现数据竞争,导致结果不一致。
- 隐式数据转换:比如Short转字符串的时候,有没有可能因为编码、格式问题导致数据被悄悄修改?比如你代码里的ASCII转换,就很容易埋下这种隐患。
- 外部资源依赖:如果代码读写了外部文件、SharedPreferences或者网络资源,这些资源的状态变化(比如文件被其他程序修改、权限变化)也会影响输出。
二、写.dat文件代码的问题分析
从你给出的代码片段来看,这里有几个明显的风险点:
冗余且危险的字符串中转
你把List<Short>转成字符串,再转ASCII字节,最后又把字符串拆成8个字符转byte,这个流程不仅效率低,还很容易丢数据:stringTransform.getBytes()默认用的是系统默认编码(比如UTF-8),再转成ASCII的话,任何超出ASCII范围(0-127)的字符都会被替换成?或者直接截断,直接破坏原始数据。- 如果
transform方法生成的字符串长度不是8的整数倍,str.length()/8会直接截断后面的字符,导致部分Short数据丢失。
未完成的位操作逻辑
代码里if (chatAt == '1')后面的逻辑没写完,但能看出来你想把8个字符('0'/'1')转成一个byte的8个位。这里如果没处理'0'的情况,或者位操作的顺序搞反了(比如高位和低位的顺序),都会生成错误的byte值。低效的处理方式
Short本身是16位的二进制数据,直接操作它的字节要比转字符串再处理高效得多,还能避免编码带来的问题。
改进思路
给你个更靠谱的写法参考,直接操作Short的字节,跳过字符串中转:
private void writeToFile(List<Short> list) throws IOException { // 用ByteBuffer来处理字节转换,更高效且安全 ByteBuffer buffer = ByteBuffer.allocate(list.size() * 2); // 每个Short占2字节 for (Short s : list) { buffer.putShort(s); } byte[] bytes = buffer.array(); // 写入文件(这里记得替换成你的文件路径) try (FileOutputStream fos = new FileOutputStream("your_file_path.dat")) { fos.write(bytes); } }
如果你的需求是把Short的二进制位拆成单个bit存成byte(比如每8个bit一个byte),那可以直接操作Short的位:
private void writeToFile(List<Short> list) throws IOException { BitSet bitSet = new BitSet(list.size() * 16); int bitIndex = 0; for (Short s : list) { for (int i = 0; i < 16; i++) { // 从高位到低位依次设置bit,根据你的需求调整顺序 boolean isSet = (s & (1 << (15 - i))) != 0; bitSet.set(bitIndex++, isSet); } } // 把BitSet转成byte数组 byte[] bytes = bitSet.toByteArray(); // 写入文件 try (FileOutputStream fos = new FileOutputStream("your_file_path.dat")) { fos.write(bytes); } }
内容的提问来源于stack exchange,提问作者JDChi
相关产品推荐
相关产品推荐

