Java中如何将含0值填充的字节数组转换为去填充字符串?
解决字节数组转字符串时截断末尾空字节(ASCII 0)的问题
你碰到的问题根源很明确:Java的String(byte[], Charset)构造函数会把整个字节数组的内容都转换成字符串,包括那些用来填充的ASCII 0(空字符)。这些空字符在控制台输出时可能看不到,但会实实在在地占据字符串长度,导致你得到16个字符的结果。
要获取只包含有效文本的字符串,核心思路是截断到第一个空字节的位置,下面是几种原生Java的实现方案:
方案一:提前遍历字节数组截取有效部分
这是最高效的方式,直接在字节数组层面找到第一个空字节的索引,再截取对应片段转换为字符串:
import java.nio.charset.StandardCharsets; public class HelloWorld{ public static void main(String []args){ byte[] name = new byte[16]; for(int i=0; i<16; i++) { name[i] = 0; } name[0] = 'A'; name[1] = 'B'; name[2] = 'C'; // 找到第一个空字节的位置 int validLength = 0; while (validLength < name.length && name[validLength] != 0) { validLength++; } // 仅转换有效字节段 String nameStr = new String(name, 0, validLength, StandardCharsets.US_ASCII); System.out.println("#"+nameStr+"#"); System.out.println(nameStr.length()); // 输出3,符合预期 } }
方案二:先转字符串再截取空字符前的内容
如果已经完成了全数组的字符串转换,也可以通过查找字符串中的空字符(\0)来截取有效部分:
import java.nio.charset.StandardCharsets; public class HelloWorld{ public static void main(String []args){ byte[] name = new byte[16]; for(int i=0; i<16; i++) { name[i] = 0; } name[0] = 'A'; name[1] = 'B'; name[2] = 'C'; String fullString = new String(name, StandardCharsets.US_ASCII); int nullCharIndex = fullString.indexOf('\0'); // 处理数组中没有空字节的边界情况 String nameStr = nullCharIndex != -1 ? fullString.substring(0, nullCharIndex) : fullString; System.out.println("#"+nameStr+"#"); System.out.println(nameStr.length()); // 输出3 } }
注意:别用trim()!
很多人会第一时间想到用String.trim(),但这个方法只能移除字符串首尾的空白字符(比如空格、制表符、换行符等),ASCII 0(\0)并不属于空白字符的范畴,所以用trim()完全无法去掉这些填充的空字节。
如果你项目中已经引入了Apache Commons Lang工具库,还可以用更简洁的方式:
import org.apache.commons.lang3.StringUtils; import java.nio.charset.StandardCharsets; public class HelloWorld{ public static void main(String []args){ byte[] name = new byte[16]; // 初始化字节数组... String nameStr = StringUtils.stripEnd(new String(name, StandardCharsets.US_ASCII), "\0"); System.out.println(nameStr.length()); // 输出3 } }
内容的提问来源于stack exchange,提问作者M.E.
相关产品推荐
相关产品推荐

