【问题标题】:Do Java and C represent a UTF char byte in the same way?Java 和 C 是否以相同的方式表示 UTF char 字节?
【发布时间】:2019-03-22 01:51:47
【问题描述】:

我正在将一个字节数组从 Java 传递给 C,我认为 Java 和 C 以相同的方式表示 UTF char 字节。

我可以这样做吗:

jbyte *bytePtr = (*env)->GetByteArrayElements(env, javaByteArray, NULL);

// javaByteArray has java bytes for the UTF chars: 'A', 'B', 'C'

unsigned char *bytePtrC = (unsigned char *) bytePtr;

printf("%c %c %c \n", bytePtrC, bytePtrC+1, bytePtrC+2);

// will this print A B C ?

【问题讨论】:

  • Afaik 不,C 使用 Ascii(8 位),而 Java 使用 UTF-16(16 位)
  • @hellow C 不一定“使用 Ascii(8 位)”。
  • @hellow:C 标准不需要 ASCII。许多 C 实现使用 ASCII,但也有其他选择。并且 C 不限于八位字符。除了char 不受C 标准限制为8 位之外,C 还支持wchar_t 类型的宽字符。

标签: java c java-native-interface utf


【解决方案1】:

没有。

二进制字节数组表示像两条短裤一样的数据是相同的。

文本是另一回事。 Java 在设计上具有 Unicode 中的 text (String, char),char 是一个两字节的 UTF-16 值。从byte[]String 的转换总是会使用这些字节的某种编码。

在java中有一个:

byte[] bytes = string.getBytes(StandardCharsets.UTF_8);

这几乎是一个 C 数组,但对于这些差异:

  • bytes.length 作为字段
  • C 有一个额外的终止 nul 字符:'\0'
  • java 字符串可以包含一个空字符;一些课程 (DataOutputStream.writeUTF8) 也将以多字节序列对其进行编码,以便与 C 字符串进行互操作。 这称为改良的 UTF-8

但没有真正的问题。只保证:

  • 使用String.getBytes(StandardCharsets.UTF_8) 而不是String.getBytes()
  • 使用new String(bytes, StandardCharsets.UTF_8) 而不是new String(bytes)
  • 永远不要将 String 和 char 用于二进制数据,因为有人会使用 C unsigned char*。它将使用两倍的内存,来回转换很慢,可能会损坏数据。
  • 关于二进制数据 (ByteBuffer.order):short、int、long 等在 java 中是 big-endian。

由于后面的版本使用平台的默认编码,不可移植。

【讨论】:

  • 谢谢,javaByteArray 来自使用 .getBytes(UTF8) 的 java 字符串,所以我应该没问题。
  • 是的;事实上,我大喊 No 是相对的;有几件事需要考虑 - 已列出。
  • 一切正常。你有智慧,有古人的智慧。
猜你喜欢
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多