【问题标题】:Remove 0-byte (UTF-8) characters in String删除字符串中的 0 字节 (UTF-8) 字符
【发布时间】:2015-05-08 02:00:45
【问题描述】:

我目前正在编写一个多人游戏,我现在正在研究它的网络方面。我设置了一个数据包系统,它的工作方式(至少使用字符串)是它需要多个字符,最多为“X”个字符。字符被转换为字节以发送到服务器。如果少于 X 个字符,则剩余字节设置为 0。问题是,在服务器上处理此信息并将其转换为字符串时,0 字节字符在我的控制台中是“□”,并且在我的 JTextPane 中不可见。如何以干净的方式从字符串中删除所有这些 0 字节字符?我不希望有另一个循环和更多变量,只是在转换为字符串之前删除 0 字节。没有人喜欢看起来很脏的代码。 :p

数据包数据:

03100101118000000000971001091051100000000
  • 03 = 数据包 ID(无关)
  • 100101118000000000 = 用户名(“dev”)
  • 971001091051100000000 = 密码(“admin”)

结果字符串:

  • usernameString = "dev□□□□□□□□□"
  • passwordString = "管理员□□□□□□□"

我尝试过的:

usernameString.replaceAll(new String(new byte[] {0}, "UTF-8"), "");
passwordString.replaceAll(new String(new byte[] {0}, "UTF-8"), "");

但是,这根本没有改变字符串。

【问题讨论】:

  • 使用一些正则表达式来计算字符串的结尾是一个或多个0
  • 如果您使用 Java 7 或更高版本,最好使用 StandardCharsets.UTF_8 常量而不是 "UTF-8" 文字。这更快,您无需处理/重新抛出UnsupportedEncodingException
  • @TagirValeev 哇,我从来没有意识到 StandardCharsets.UTF_8"UTF-8" 文字相比要快多少。非常感谢。

标签: java string utf-8 network-programming bytearray


【解决方案1】:

由于所有的零都出现在字符串的末尾,即使没有正则表达式,您也可以解决这个问题:

static String trimZeros(String str) {
    int pos = str.indexOf(0);
    return pos == -1 ? str : str.substring(0, pos);
}

usernameString = trimZeros(usernameString);
passwordString = trimZeros(passwordString);

【讨论】:

  • 我比假设0 只出现在末尾的正则表达式更喜欢这个。
  • @TagirValeev 由于数据包的性质,除非最后是未填充的字符,否则永远不会有 0 字节。不过,这是一个很好的安全预防措施。
【解决方案2】:
usernameString = // replace 1 or more \0 at the end of the string
    usernameString.replaceAll("\0+$", "");

\0 是数值 0(有时称为 NUL)的 Unicode 字符的转义。换句话说:

System.out.println((int) "\0".charAt(0)); // prints 0

您尝试的方法似乎也对我有用。 (见Ideone example。)不知道为什么它不适合你。可能还有另一个问题。确保您正在重新分配结果。 ; )

【讨论】:

  • 这对我不起作用,因为字符串中的 0 字节字符之前没有“\”,也没有实际的“0”。该字符本质上为空。
  • 查看我的编辑。抱歉,我想我最初可以解释一下。 \ 没有出现在字符串中,这是一个转义。
  • 在那种情况下这对我来说效果很好。我选择了另一个答案作为 the 答案,因为它看起来更简洁,但是这段代码很实用,而且绝对可以完成工作,谢谢!
猜你喜欢
  • 2019-01-13
  • 2013-12-22
  • 2012-01-20
  • 2018-01-05
  • 2012-03-04
  • 2012-01-19
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多