字符串和字节数组之间的转换
原文:https://www.studytonight.com/java-examples/conversion-between-string-and-byte-array
我们经常需要将一个字符串转换成字节数组(编码),或者将一个字节数组转换成字符串(解码)。字符串是 Unicode 字符值的序列(或数组)。我们可以将数组的每个字符映射到一个字节值,并生成一个字节数组。字符集提供字符和字节之间的映射。在编码和解码过程中需要这个字符集。在本教程中,我们将学习字符串和字节数组之间的转换。
字符串到字节数组(编码)
有几种方法可以从字符串中获取字节数组。让我们学习如何做到这一点。
使用 getBytes()方法
String 类的 getBytes()方法提供了一种获取字节数组的便捷方法。String
类包含 getBytes()方法的三个重载版本。
- getBytes() -使用平台的默认字符集生成字节数组。
- getBytes(字符串字符集名称)-使用提供的命名字符集生成字节数组。
- getBytes(字符集字符集)-使用字符集实例生成字节数组。
让我们使用其中的每一个并查看输出。
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
byte[] byteArr = s.getBytes();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,33]
没有任何字符集的 getBytes()方法使用平台的默认字符集。这使得字节数组依赖于平台,在其他系统上可能无法正确解码。我们可以通过使用 Charset.defaultCharset()方法来查看默认的字符集。
import java.nio.charset.Charset;
public class Demo
{
public static void main(String[] args)
{
System.out.print("Default Charset: " + Charset.defaultCharset());
}
}
默认字符集:UTF-8
字符串获取字节(字符串字符集名)方法
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String s = "demo!";
String namedCharset = "UTF-16";
byte[] byteArr = s.getBytes(namedCharset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
我们需要确保使用有效命名的字符集。否则,我们将获得不支持编码异常。
import java.io.UnsupportedEncodingException;
public class Demo
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String s = "demo!";
String namedCharset = "UTF-40";//UTF-40 is not a valid encoding
byte[] byteArr = s.getBytes(namedCharset);
}
}
线程“main”Java . io . unsupportdencodingenexception:UTF-40 在 Java . base/Java . lang . stringcoding . encode(stringcoding . Java:440) 在 Java . base/Java . lang . string . getbytes(string . Java:959) 在 Demo.main(Demo.java:10)
字符串获取字节(字符集)方法
import java.nio.charset.Charset;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
Charset charset = Charset.forName("UTF-16");
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
我们还可以使用标准字符集来创建字符集实例。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
Charset charset = StandardCharsets.UTF_16;
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
使用字符集实例将用默认替换字节替换不支持的字符。在不支持字符的情况下,其他两个重载没有定义的行为。我们可以在下面的输出中看到,所有表情符号都被默认替换字节值 63 所替换。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo????????????";
Charset charset = StandardCharsets.ISO_8859_1;
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,63,63,63]
使用字符集编码()方法
我们可以直接使用 Charset 类的 encode()方法,而不是使用 getBytes(Charset charset)方法。此方法还将使用默认替换字节来替换不支持的字符。它返回一个 CharBuffer,我们使用 array()方法将其转换为字节数组。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo{
public static void main(String args[])
{
String s = "demo????????????";
Charset charset = StandardCharsets.ISO_8859_1;
byte[] byteArr = charset.encode(s).array();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,63,63,63,0,0,0]
使用字符集编码器
CharsetEncoder 为我们提供了更多对编码过程的控制。我们可以在不支持的字符或格式错误的输入(如果字符序列不是有效的 Unicode 序列)的情况下定义编码。
我们将首先创建一个字符集编码器,并定义编码过程。我们可以使用像 onMalformedInput()或 onUnmappableCharacter()这样的方法来实现这一点。
接下来,我们将使用 encode()方法来执行编码。
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo {
public static void main(String args[]) throws CharacterCodingException
{
String s = "demo????????????";
//Creating the encoder and defining the encoding behavior
CharsetEncoder charsetEncoder = StandardCharsets.ISO_8859_1.newEncoder();
charsetEncoder.onMalformedInput(CodingErrorAction.IGNORE);//Ignore malformed input
charsetEncoder.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(new byte[] {-121});//Replace unmappable character with 0
byte[] byteArr = charsetEncoder.encode(CharBuffer.wrap(s)).array();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,-121,-121,-121,0,0,0]
在上面的代码中,我们忽略了格式错误的输入,我们用-121 替换了不可映射的字符(在我们的例子中是表情符号)。我们也可以使用 REPORT 返回一个 CoderResult 对象或者抛出一个 CharacterCodingException。
字节数组到字符串
就像编码一样,解码也需要字符集。让我们学习如何解码字节数组以获取底层字符串。
使用字符串构造器
字符串构造器可以接受一个字节数组,并使用该数组初始化一个字符串。这种方法与 getBytes()方法正好相反。
我们只需要将字节数组传递给构造器,字符串将使用系统的默认字符集生成。不建议使用这种方法,因为字符串可能没有使用相同的默认字符集进行编码。在下面的示例中,原始字符串是使用 UTF-16 字符集编码的,但是系统的默认解码是 UTF-8。因为它,我们不会得到预期的结果。
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
String stringFromBytes = new String(byteArr);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:??d e m o!
使用命名字符集:
我们还可以向构造器传递一个命名字符集。如果提到无效字符集,则会引发错误。
import java.io.UnsupportedEncodingException;
public class Demo
{
public static void main(String args[]) throws UnsupportedEncodingException
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
String stringFromBytes = new String(byteArr, "UTF-16");
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
使用字符集实例:
字符串构造器也可以采用一个字符集类实例进行解码。
import java.nio.charset.Charset;
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
Charset charset = Charset.forName("UTF-16");
String stringFromBytes = new String(byteArr, charset);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
我们也可以使用标准字符集。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
Charset charset = StandardCharsets.UTF_16;
String stringFromBytes = new String(byteArr, charset);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
使用 Charset.decode()方法
像 encode()方法一样,Charset 类提供了一个 decode()方法来解码字节数组。如果数组包含无效输入,则用默认字符替换它。
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String[] args)
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33, -10};
Charset charset = StandardCharsets.UTF_16;
String stringFromBytes = charset.decode(ByteBuffer.wrap(byteArr)).toString();
System.out.print("String from byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!?
使用字符集解码器
上面讨论的所有方法都在内部使用字符集解码器。它为我们提供了对解码过程的更多控制。就像字符集编码器一样,我们可以忽略、替换或报告不可映射的字符或格式错误的字符。在下面的代码中,我们将这些字符替换为星号(*)。
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String[] args) throws CharacterCodingException
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33, -10};
CharsetDecoder charsetDecoder = StandardCharsets.UTF_16.newDecoder();
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE)
.onMalformedInput(CodingErrorAction.REPLACE)
.replaceWith("*");//Replace unmappable and malformed characters with *
String stringFromBytes = charsetDecoder.decode(ByteBuffer.wrap(byteArr)).toString();
System.out.print("String from Byte Array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!*
摘要
有许多不同的方法可以将字符串转换为字节数组,反之亦然。String
类本身提供了三个重载的 getBytes()方法来创建一个字节数组。我们可以使用String
类构造器从字节数组中获取字符串。建议使用字符集编码器和字符集解码器进行转换。它们为编码和解码过程提供了更多的自由和控制。