将字符串编码为 UTF-8
Posted
技术标签:
【中文标题】将字符串编码为 UTF-8【英文标题】:Encode String to UTF-8 【发布时间】:2011-08-09 10:40:18 【问题描述】:我有一个带有“ñ”字符的字符串,但我遇到了一些问题。我需要将此字符串编码为 UTF-8 编码。这个方法我试过了,还是不行:
byte ptext[] = myString.getBytes();
String value = new String(ptext, "UTF-8");
如何将该字符串编码为 utf-8?
【问题讨论】:
目前还不清楚您到底想做什么。 myString 是否正确包含 ñ 字符并且您在将其转换为字节数组时遇到问题(在这种情况下,请参阅 Peter 和 Amir 的答案),或者 myString 是否已损坏并且您正在尝试修复它(在这种情况下,请参阅 Joachim 的答案还有我)? 我需要将 myString 发送到 utf-8 编码的服务器,我需要将“ñ”字符转换为 utf-8 编码。 好吧,如果该服务器需要 UTF-8,那么您需要发送它的是字节,而不是字符串。因此,根据彼得的回答,在第一行中指定编码并删除第二行。 @Michael:我同意目前尚不清楚这里的真正意图是什么。似乎有很多问题,人们试图在字符串和字节之间进行显式转换,而不是让In,OutputStreamRead,Writers
为他们做这件事。我想知道为什么?
@Michael:谢谢,我想这是有道理的。但这也使它变得比需要的更难,不是吗?我不太喜欢以这种方式工作的语言,因此尽量避免使用它们。我认为 Java 的字符串模型而不是字节模型让事情变得容易多了。 Perl 和 Python 也共享“一切都是 Unicode 字符串”模型。是的,如果你在这三个方面工作,你仍然可以获得字节,但实际上你真正需要的似乎很少:这是相当低级的。另外,如果您知道我的意思,那感觉有点像在错误的方向上刷猫。 :)
【参考方案1】:
如何使用
ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(myString)
【讨论】:
但是我如何获得一个编码的字符串呢?它返回一个 ByteBuffer @Alex:不可能拥有 UTF-8 编码的 Java 字符串。你想要字节,所以要么直接使用 ByteBuffer (如果你的目标是通过网络集合发送它甚至可能是最好的解决方案)或调用 array() 来获取一个字节[] 其他可能有用的方法是使用 Guava 的 Charsets.UTF_8 枚举而不是可能抛出 UnsupportedEncodingException 的字符串。字符串 -> 字节:myString.getBytes(Charsets.UTF_8)
,字节 -> 字符串:new String(myByteArray, Charsets.UTF_8)
。
更好的是,使用StandardCharsets.UTF_8
。在 Java 1.7+ 中可用。
array()
返回的数组很可能会比需要的更大并被填充,因为它是ByteBuffer
s 内部数组。最好使用string.getBytes(StandardCharsets.UTF_8)
,它将返回一个大小正确的新数组。【参考方案2】:
String
Java 中的对象使用无法修改的 UTF-16 编码。
唯一可以有不同编码的是byte[]
。所以如果你需要 UTF-8 数据,那么你需要一个byte[]
。如果您的 String
包含意外数据,则问题出在较早的地方,将某些二进制数据错误地转换为 String
(即,它使用了错误的编码)。
【讨论】:
从技术上讲,byte[] 没有任何编码。字节数组加编码可以给你字符串。 @Peter:是的。但是给它附加一个编码只对byte[]
有意义,对String
没有意义(除非编码是UTF-16,在这种情况下它是有意义的,但它仍然是不必要的信息)。
String objects in Java use the UTF-16 encoding that can't be modified.
你有这个报价的官方来源吗?
@AhmadHajjar docs.oracle.com/javase/10/docs/api/java/lang/… :“Java 平台在 char 数组以及 String 和 StringBuffer 类中使用 UTF-16 表示。”【参考方案3】:
在 Java7 中你可以使用:
import static java.nio.charset.StandardCharsets.*;
byte[] ptext = myString.getBytes(ISO_8859_1);
String value = new String(ptext, UTF_8);
与getBytes(String)
相比,它的优势在于它不声明throws UnsupportedEncodingException
。
如果您使用的是较旧的 Java 版本,您可以自己声明字符集常量:
import java.nio.charset.Charset;
public class StandardCharsets
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
public static final Charset UTF_8 = Charset.forName("UTF-8");
//....
【讨论】:
这是正确的答案。如果有人想使用字符串数据类型,他可以以正确的格式使用它。其余的答案都指向字节格式的类型。 工作在 6。谢谢。 对我来说也是正确的答案。但是有一件事,当我如上所述使用时,德语字符变为?。所以,我用了这个: byte[] ptext = myString.getBytes(UTF_8);字符串值 = 新字符串(ptext,UTF_8);这很好用。 代码示例没有意义。如果您首先转换为 ISO-8859-1,那么该字节数组是 not UTF-8,因此下一行是完全不正确的。当然,它适用于 ASCII 字符串,但您也可以制作一个简单的副本:String value = new String(myString);
.【参考方案4】:
使用byte[] ptext = String.getBytes("UTF-8");
代替getBytes()
。 getBytes()
使用所谓的“默认编码”,可能不是 UTF-8。
【讨论】:
@Michael:他显然无法从字符串中获取字节。 getBytes(encoding) 是如何漏掉重点的?我认为第二行只是为了检查他是否可以将其转换回来。 我把它解释为有一个损坏的字符串,并试图通过转换为字节来“修复”它(常见的误解)。没有实际迹象表明第二行只是检查结果。 @Michael,不,没有,这只是我的解释。你的完全不同。 @Peter:你说得对,我们需要 Alex 澄清他的真正意思。除非编辑答案,否则无法撤销反对票...【参考方案5】:Java 字符串在内部总是以 UTF-16 编码 - 但您确实应该这样考虑:编码是在字符串和字节之间进行转换的一种方式。
因此,如果您遇到编码问题,等到您拥有 String 时,再修复已为时已晚。您需要修复从文件、数据库或网络连接创建该字符串的位置。
【讨论】:
认为字符串在内部编码为 UTF-16 是一个常见的错误。通常它们是,但如果它只是 String 类的特定实现细节。由于无法通过公共 API 访问字符数据的内部存储,因此特定的 String 实现可能会决定使用任何其他编码。 @jarnbjo:API 明确声明“字符串表示 UTF-16 格式的字符串”。使用其他任何东西作为内部格式都会非常低效,而且我知道的所有实际实现都在内部使用 UTF-16。所以除非你能引用一个不能引用的例子,否则你就是在进行非常荒谬的分叉。 区分公共访问和数据结构的内部表示是否荒谬? JVM(只要它与 VM 相关)使用 UTF-8 进行字符串编码,例如在类文件中。 java.lang.String 的实现与 JVM 分离,如果您确实需要意识到您的答案不正确,我可以使用任何其他编码作为内部表示轻松地为您实现该类。在大多数情况下,使用 UTF-16 作为内部格式在内存消耗方面也非常低效,我不明白为什么,例如嵌入式硬件的 Java 实现不会优化内存而不是性能。 @jarnbjo:再一次:只要你不能给出标准 API 实现确实在内部使用 UTF-16 以外的其他东西来实现字符串的 JVM 的具体示例,我的说法是正确的。不,String 类并没有真正与 JVM 解耦,原因是 intern() 和常量池。【参考方案6】:你可以试试这个方法。
byte ptext[] = myString.getBytes("ISO-8859-1");
String value = new String(ptext, "UTF-8");
【讨论】:
我快疯了。感谢您首先获得“ISO-8859-1”中的字节是解决方案。 这是错误的。如果您的字符串包含 Unicode 字符,将其转换为 8859-1 会引发异常,或者更糟的是给您一个无效的字符串(可能是没有代码点 0x100 及以上字符的字符串)。 完美运行【参考方案7】:我很快就解决了这个问题并设法通过以下方式解决了它
首先我需要导入
import java.nio.charset.Charset;
然后我必须声明一个常量来使用UTF-8
和ISO-8859-1
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Charset ISO = Charset.forName("ISO-8859-1");
然后我可以通过以下方式使用它:
String textwithaccent="Thís ís a text with accent";
String textwithletter="Ñandú";
text1 = new String(textwithaccent.getBytes(ISO), UTF_8);
text2 = new String(textwithletter.getBytes(ISO),UTF_8);
【讨论】:
完美解决方案。【参考方案8】:String value = new String(myString.getBytes("UTF-8"));
并且,如果您想从编码为“ISO-8859-1”的文本文件中读取:
String line;
String f = "C:\\MyPath\\MyFile.txt";
try
BufferedReader br = Files.newBufferedReader(Paths.get(f), Charset.forName("ISO-8859-1"));
while ((line = br.readLine()) != null)
System.out.println(new String(line.getBytes("UTF-8")));
catch (IOException ex)
//...
【讨论】:
【参考方案9】:我使用下面的代码通过指定编码格式来编码特殊字符。
String text = "This is an example é";
byte[] byteText = text.getBytes(Charset.forName("UTF-8"));
//To get original string from byte.
String originalString= new String(byteText , "UTF-8");
【讨论】:
【参考方案10】:如何配置 NetBeans 默认编码 UTF-8 的快速分步指南。结果,NetBeans 将以 UTF-8 编码创建所有新文件。
NetBeans 默认编码 UTF-8 分步指南
转到 NetBeans 安装目录中的 etc 文件夹
编辑 netbeans.conf 文件
找到 netbeans_default_options 行
在该行的引号内添加 -J-Dfile.encoding=UTF-8
(例如:netbeans_default_options="-J-Dfile.encoding=UTF-8"
)
重启 NetBeans
您将 NetBeans 的默认编码设置为 UTF-8。
您的 netbeans_default_options 可能在引号内包含其他参数。在这种情况下,请在字符串末尾添加 -J-Dfile.encoding=UTF-8。用空格将其与其他参数隔开。
例子:
netbeans_default_options="-J-client -J-Xss128m -J-Xms256m -J-XX:PermSize=32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dfile.encoding=UTF-8"
这里是链接for Further Details
【讨论】:
【参考方案11】:这解决了我的问题
String inputText = "some text with escaped chars"
InputStream is = new ByteArrayInputStream(inputText.getBytes("UTF-8"));
【讨论】:
以上是关于将字符串编码为 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章
如何将 default.html 的字符编码设置为 UTF-8?
如何使用 BeautifulSoup 将 UTF-8 编码的 HTML 正确解析为 Unicode 字符串? [复制]
将 UTF-8 编码的 NSData 转换为 NSString