Java 如何将字节数组转换为字符串,反之亦然?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1536054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:56:23  来源:igfitidea点击:

How to convert byte array to string and vice versa?

java

提问by Jyotsna

I have to convert a byte array to string in Android, but my byte array contains negative values.

我必须在 Android 中将字节数组转换为字符串,但我的字节数组包含负值。

If I convert that string again to byte array, values I am getting are different from original byte array values.

如果我再次将该字符串转换为字节数组,我得到的值与原始字节数组值不同。

What can I do to get proper conversion? Code I am using to do the conversion is as follows:

我该怎么做才能获得正确的转换?我用来进行转换的代码如下:

// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);

// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++) 
System.out.println("by1["+i+"] >> "+str1);

I am stuck in this problem.

我被这个问题困住了。

采纳答案by omerkudat

Your byte array must have some encoding. The encoding cannot be ASCII if you've got negative values. Once you figure that out, you can convert a set of bytes to a String using:

你的字节数组必须有一些编码。如果您有负值,则编码不能是 ASCII。一旦你弄清楚了,你可以使用以下方法将一组字节转换为字符串:

byte[] bytes = {...}
String str = new String(bytes, "UTF-8"); // for UTF-8 encoding

There are a bunch of encodings you can use, look at the Charset class in the Sun javadocs.

您可以使用多种编码,请查看Sun javadocs中的 Charset 类。

回答by Toad

A string is a collection of char's (16bit unsigned). So if you are going to convert negative numbers into a string, they'll be lost in translation.

字符串是字符的集合(16 位无符号)。因此,如果您要将负数转换为字符串,它们将在翻译中丢失。

回答by Maurice Perry

Try to specify an 8-bit charset in both conversions. ISO-8859-1 for instance.

尝试在两种转换中指定一个 8 位字符集。例如 ISO-8859-1。

回答by sfussenegger

Using new String(byOriginal)and converting back to byte[]using getBytes()doesn't guarantee two byte[]with equal values. This is due to a call to StringCoding.encode(..)which will encode the Stringto Charset.defaultCharset(). During this encoding, the encoder might choose to replace unknown characters and do other changes. Hence, using String.getBytes()might not return an equal array as you've originally passed to the constructor.

使用new String(byOriginal)和转换回byte[]使用getBytes()并不能保证两个byte[]值相等。这是由于调用StringCoding.encode(..)将对Stringto进行编码Charset.defaultCharset()。在此编码期间,编码器可能会选择替换未知字符并进行其他更改。因此, usingString.getBytes()可能不会像您最初传递给构造函数那样返回相等的数组。

回答by Stephen C

The root problem is (I think) that you are unwittingly using a character set for which:

根本问题是(我认为)您在不知不觉中使用了以下字符集:

 bytes != encode(decode(bytes))

in some cases. UTF-8 is an example of such a character set. Specifically, certain sequences of bytes are not valid encodings in UTF-8. If the UTF-8 decoder encounters one of these sequences, it is liable to discard the offending bytes or decode them as the Unicode codepoint for "no such character". Naturally, when you then try to encode the characters as bytes the result will be different.

在某些情况下。UTF-8 就是这种字符集的一个例子。具体来说,某些字节序列不是 UTF-8 中的有效编码。如果 UTF-8 解码器遇到这些序列之一,它很可能会丢弃有问题的字节或将它们解码为“没有这样的字符”的 Unicode 代码点。当然,当您尝试将字符编码为字节时,结果会有所不同。

The solution is:

解决办法是:

  1. Be explicit about the character encoding you are using; i.e. use a String constructor and String.toByteArraymethod with an explicit charset.
  2. Use the right character set for your byte data ... or alternatively one (such as "Latin-1" where all byte sequences map to valid Unicode characters.
  3. If your bytes are (really) binary data and you want to be able to transmit / receive them over a "text based" channel, use something like Base64 encoding ... which is designed for this purpose.
  1. 明确说明您使用的字符编码;即使用String.toByteArray带有显式字符集的 String 构造函数和方法。
  2. 为您的字节数据使用正确的字符集......或另一种(例如“Latin-1”,其中所有字节序列都映射到有效的 Unicode 字符。
  3. 如果您的字节是(真的)二进制数据,并且您希望能够通过“基于文本”的通道传输/接收它们,请使用 Base64 编码之类的东西......这是为此目的而设计的

回答by Michael Borgwardt

The "proper conversion" between byte[]and Stringis to explicitly state the encoding you want to use. If you start with a byte[]and it does not in fact contain text data, there is no"proper conversion". Strings are for text, byte[]is for binary data, and the only really sensible thing to do is to avoidconverting between them unless you absolutely have to.

byte[]和之间的“正确转换”String是明确说明您要使用的编码。如果您以 a 开头byte[]并且它实际上不包含文本数据,则没有“正确转换”。Strings 用于文本,byte[]用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非您绝对必须这样做。

If you really must use a Stringto hold binary data then the safest way is to use Base64encoding.

如果您确实必须使用 aString来保存二进制数据,那么最安全的方法是使用Base64编码。

回答by Goutom Roy

Use Base64 and solve your problem.Its too much easy to use. http://iharder.sourceforge.net/current/java/base64/

使用 Base64 解决您的问题。它太容易使用了。 http://iharder.sourceforge.net/current/java/base64/

回答by Ravindranath Akila

We just need to construct a new Stringwith the array: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/

我们只需要用String数组构造一个新的:http: //www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/

String s = new String(bytes);

The bytes of the resulting string differs depending on what charset you use. new String(bytes) and new String(bytes, Charset.forName("utf-8")) and new String(bytes, Charset.forName("utf-16")) will all have different byte arrays when you call String#getBytes() (depending on the default charset)

结果字符串的字节因您使用的字符集而异。new String(bytes) 和 new String(bytes, Charset.forName("utf-8")) 和 new String(bytes, Charset.forName("utf-16")) 在调用 String# 时都会有不同的字节数组getBytes()(取决于默认字符集)

回答by Rupesh

Why was the problem:As someone already specified: If you start with a byte[] and it does not in fact contain text data, there is no "proper conversion". Strings are for text, byte[] is for binary data, and the only really sensible thing to do is to avoid converting between them unless you absolutely have to.

为什么会出现问题:正如有人已经指定的那样: 如果您以 byte[] 开头并且它实际上不包含文本数据,则没有“正确的转换”。字符串用于文本,byte[] 用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非您绝对必须这样做。

I was observing this problem when I was trying to create byte[] from a pdf file and then converting it to String and then taking the String as input and converting back to file.

当我尝试从 pdf 文件创建 byte[] 然后将其转换为 String 然后将 String 作为输入并转换回文件时,我观察到了这个问题。

So make sure your encoding and decoding logic is same as I did. I explicitly encoded the byte[] to Base64 and decoded it to create the file again.

所以请确保您的编码和解码逻辑与我所做的相同。我将 byte[] 显式编码为 Base64 并将其解码以再次创建文件。

Use-case:Due to some limitation I was trying to sent byte[]in request(POST)and the process was as follows:

用例:由于某些限制,我尝试发送byte[]request(POST)过程如下:

PDF File >> Base64.encodeBase64(byte[]) >> String >> Send in request(POST) >> receive String >> Base64.decodeBase64(byte[]) >> create binary

PDF文件>> Base64.encodeBase64(byte[])>>字符串>>发送请求(POST)>>接收字符串>>Base64.decodeBase64(byte[])>>创建二进制

Try this and this worked for me..

试试这个,这对我有用..

File file = new File("filePath");

        byte[] byteArray = new byte[(int) file.length()];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read(byteArray);

            String byteArrayStr= new String(Base64.encodeBase64(byteArray));

            FileOutputStream fos = new FileOutputStream("newFilePath");
            fos.write(Base64.decodeBase64(byteArrayStr.getBytes()));
            fos.close();
        } 
        catch (FileNotFoundException e) {
            System.out.println("File Not Found.");
            e.printStackTrace();
        }
        catch (IOException e1) {
            System.out.println("Error Reading The File.");
            e1.printStackTrace();
        }

回答by LeD

This works fine for me:

这对我来说很好用:

String cd="Holding some value";

Converting from string to byte[]:

从字符串转换为字节[]:

byte[] cookie = new sun.misc.BASE64Decoder().decodeBuffer(cd);

Converting from byte[] to string:

从字节 [] 转换为字符串:

cd = new sun.misc.BASE64Encoder().encode(cookie);