我必须在Android中将字节数组转换为字符串,但我的字节数组包含负值。
如果我再次将该字符串转换为字节数组,则我得到的值与原始字节数组值不同。
我可以做些什么来获得正确的转换?我用来进行转换的代码如下:
// 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);
我遇到了这个问题。
答案 0 :(得分:324)
您的字节数组必须有一些编码。如果您有负值,则编码不能是ASCII。一旦弄明白,就可以使用:
将一组字节转换为Stringbyte[] bytes = {...}
String str = new String(bytes, "UTF-8"); // for UTF-8 encoding
您可以使用一堆编码,查看Sun javadocs中的Charset类。
答案 1 :(得分:98)
byte[]
和String
之间的“正确转换”是明确说明您要使用的编码。如果您从byte[]
开始并且实际上并不包含文本数据,则没有“正确转换”。 String
用于文本,byte[]
用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非您绝对不得不这样做。
如果您真的必须使用String
来保存二进制数据,那么最安全的方法是使用Base64编码。
答案 2 :(得分:36)
根本问题是(我认为)您无意中使用了以下字符集:
bytes != encode(decode(bytes))
在某些情况下。 UTF-8是这种字符集的一个例子。具体而言,某些字节序列不是UTF-8中的有效编码。如果UTF-8解码器遇到这些序列之一,它可能会丢弃有问题的字节或将它们解码为“无此字符”的Unicode代码点。当然,当您尝试将字符编码为字节时,结果会有所不同。
解决方案是:
String.toByteArray
方法。答案 3 :(得分:31)
我们只需要使用数组构建一个新的String
:http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/
String s = new String(bytes);
结果字符串的字节根据您使用的字符集而有所不同。调用String#时,新的String(字节)和新的String(字节,字符串,Charset.forName(“utf-8”))和新的字符串(字节,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字符串,字节数getBytes()(取决于默认字符集)
答案 4 :(得分:12)
使用new String(byOriginal)
并使用byte[]
转换回getBytes()
并不能保证两个byte[]
具有相同的值。这是因为对 StringCoding.encode(..)
的调用会将String
编码为 Charset.defaultCharset()
。在此编码期间,编码器可能会选择替换未知字符并执行其他更改。因此,使用String.getBytes()
可能不会返回与您最初传递给构造函数相同的数组。
答案 5 :(得分:9)
为什么会出现问题:正如有人指定的那样: 如果以字节[]开头并且实际上不包含文本数据,则没有“正确的转换”。字符串用于文本,byte []用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非你绝对不得不这样做。
当我尝试从pdf文件创建byte []然后将其转换为String然后将String作为输入并转换回文件时,我正在观察此问题。
因此请确保您的编码和解码逻辑与我一样。我明确地将byte []编码为Base64并对其进行解码以再次创建文件。
使用情况:强>
由于某些限制,我尝试在byte[]
中发送request(POST)
,过程如下:
PDF文件&gt;&gt; Base64.encodeBase64(byte [])&gt;&gt;字符串&gt;&gt;发送请求(POST)&gt;&gt;接收字符串&gt;&gt; Base64.decodeBase64(byte [])&gt;&gt;创建二进制文件
试试这个,这对我有用..
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();
}
答案 6 :(得分:6)
这对我来说很好用:
String cd="Holding some value";
从字符串转换为字节[]:
byte[] cookie = new sun.misc.BASE64Decoder().decodeBuffer(cd);
从byte []转换为string:
cd = new sun.misc.BASE64Encoder().encode(cookie);
答案 7 :(得分:5)
我确实注意到任何答案都没有的东西。您可以将字节数组中的每个字节转换为字符,并将它们放在char数组中。然后字符串是
new String(cbuf)
,其中cbuf是char数组。要转换回来,循环遍历字符串,将每个字符转换为字节以放入字节数组,此字节数组将与第一个字节数组相同。
public class StringByteArrTest {
public static void main(String[] args) {
// put whatever byte array here
byte[] arr = new byte[] {-12, -100, -49, 100, -63, 0, -90};
for (byte b: arr) System.out.println(b);
// put data into this char array
char[] cbuf = new char[arr.length];
for (int i = 0; i < arr.length; i++) {
cbuf[i] = (char) arr[i];
}
// this is the string
String s = new String(cbuf);
System.out.println(s);
// converting back
byte[] out = new byte[s.length()];
for (int i = 0; i < s.length(); i++) {
out[i] = (byte) s.charAt(i);
}
for (byte b: out) System.out.println(b);
}
}
答案 8 :(得分:5)
private static String toHexadecimal(byte[] digest){
String hash = "";
for(byte aux : digest) {
int b = aux & 0xff;
if (Integer.toHexString(b).length() == 1) hash += "0";
hash += Integer.toHexString(b);
}
return hash;
}
答案 9 :(得分:2)
下面是一些将字节数组转换为字符串的方法。我测试过它们效果很好。
public String getStringFromByteArray(byte[] settingsData) {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(settingsData);
Reader reader = new BufferedReader(new InputStreamReader(byteArrayInputStream));
StringBuilder sb = new StringBuilder();
int byteChar;
try {
while((byteChar = reader.read()) != -1) {
sb.append((char) byteChar);
}
}
catch(IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public String getStringFromByteArray(byte[] settingsData) {
StringBuilder sb = new StringBuilder();
for(byte willBeChar: settingsData) {
sb.append((char) willBeChar);
}
return sb.toString();
}
答案 10 :(得分:2)
javax.xml.bind.DatatypeConverter
应该这样做:
byte [] b = javax.xml.bind.DatatypeConverter.parseHexBinary("E62DB");
String s = javax.xml.bind.DatatypeConverter.printHexBinary(b);
答案 11 :(得分:1)
尽管
new String(bytes, "UTF-8")
是正确的,它抛出一个UnsupportedEncodingException
,它迫使您处理一个已检查的异常。从Java 1.6开始,您可以使用另一个构造函数作为替代,以将字节数组转换为String
:
new String(bytes, StandardCharsets.UTF_8)
这不会引发任何异常。
也应使用StandardCharsets.UTF_8
进行转换:
"test".getBytes(StandardCharsets.UTF_8)
同样,您避免处理被检查的异常。
答案 12 :(得分:1)
我用这种方法成功地将字节数组转换为字符串:
public static String byteArrayToString(byte[] data){
String response = Arrays.toString(data);
String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];
for (int i=0, len=bytes.length; i<len; i++) {
bytes[i] = Byte.parseByte(byteValues[i].trim());
}
String str = new String(bytes);
return str.toLowerCase();
}
答案 13 :(得分:1)
虽然base64编码是安全的,并且可以争辩“正确的答案”,但我到这里寻找一种方法将Java字节数组转换为Java String或从Java String转换。也就是说,字节数组的每个成员在其String对应项中保持不变,编码/传输不需要额外的空间。
描述8位透明编码的 This answer对我非常有帮助。我在TB级二进制数据上使用ISO-8859-1
来回成功转换(二进制&lt; - &gt; String),而没有base64编码所需的膨胀空间要求,因此对我的用例YMMV是安全的。< / p>
This was also helpful解释何时/是否应该进行实验。
答案 14 :(得分:0)
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
private static String base64Encode(byte[] bytes)
{
return new BASE64Encoder().encode(bytes);
}
private static byte[] base64Decode(String s) throws IOException
{
return new BASE64Decoder().decodeBuffer(s);
}
答案 15 :(得分:0)
这个对我来说最多适用于Android Q:
您可以使用以下方法将十六进制字符串转换为字符串
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var x = 0
var y = 0
while(x<10){
while(y<10){
let button = UIButton(frame: CGRect(x: (x+1)*50, y: (y+1)*50, width: 50, height: 50))
button.backgroundColor = .green
button.setTitle("(" + String(x) + ", " + String(y) + ")", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
y+=1
}
x+=1
}
}
@objc func buttonAction(sender: UIButton!) {
print("Button " + sender.title(for: .normal)! + " tapped")
}
}
使用以下命令将字节数组转换为十六进制字符串
public static String hexToString(String hex) {
StringBuilder sb = new StringBuilder();
char[] hexData = hex.toCharArray();
for (int count = 0; count < hexData.length - 1; count += 2) {
int firstDigit = Character.digit(hexData[count], 16);
int lastDigit = Character.digit(hexData[count + 1], 16);
int decimal = firstDigit * 16 + lastDigit;
sb.append((char)decimal);
}
return sb.toString();
}
答案 16 :(得分:-1)
您可以使用简单的for循环进行转换:
public void byteArrToString(){
byte[] b = {'a','b','$'};
String str = "";
for(int i=0; i<b.length; i++){
char c = (char) b[i];
str+=c;
}
System.out.println(str);
}
答案 17 :(得分:-1)
尝试在两次转换中指定8位字符集。例如ISO-8859-1。
答案 18 :(得分:-1)
这是工作代码。
// Encode byte array into string . TemplateBuffer1 is my bytearry variable.
String finger_buffer = Base64.encodeToString(templateBuffer1, Base64.DEFAULT);
Log.d(TAG, "Captured biometric device->" + finger_buffer);
// Decode String into Byte Array. decodedString is my bytearray[]
decodedString = Base64.decode(finger_buffer, Base64.DEFAULT);
答案 19 :(得分:-1)
使用String
从ByteArrayInputStream
读取字节,并用BufferedReader
包装,这是Char Stream而不是Byte Stream,它将字节数据转换为String。
package com.cs.sajal;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
public class TestCls {
public static void main(String[] args) {
String s=new String("Sajal is a good boy");
try
{
ByteArrayInputStream bis;
bis=new ByteArrayInputStream(s.getBytes("UTF-8"));
BufferedReader br=new BufferedReader(new InputStreamReader(bis));
System.out.println(br.readLine());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
输出是:
Sajal是一个好孩子
答案 20 :(得分:-2)
InputStream is = new FileInputStream("/home/kalt/Desktop/SUDIS/READY/ds.bin");
byte[] bytes = IOUtils.toByteArray(is);
答案 21 :(得分:-3)
public class byteString {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String msg = "Hello";
byte[] buff = new byte[1024];
buff = msg.getBytes("UTF-8");
System.out.println(buff);
String m = new String(buff);
System.out.println(m);
}
}
答案 22 :(得分:-3)
字符串是char的集合(16位无符号)。因此,如果您要将负数转换为字符串,它们将在翻译中丢失。
答案 23 :(得分:-5)
使用Base64并解决您的问题。它太易于使用了。 http://iharder.sourceforge.net/current/java/base64/