Java 如何将字节数组转换为字符串,反之亦然?
我必须在Android中将字节数组转换为字符串,但我的字节数组包含负值 如果我再次将该字符串转换为字节数组,则得到的值与原始字节数组值不同 我能做些什么来获得正确的转换?我用于进行转换的代码如下所示:Java 如何将字节数组转换为字符串,反之亦然?,java,Java,我必须在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 >>
// 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);
//将字节arr转换为str的代码:
字节[]由_original={0,1,-2,3,-4,-5,6};
String str1=新字符串(由_原件);
System.out.println(“str1>>”+str1);
//将str转换为字节arr的代码:
byte[]by_new=str1.getBytes();
对于(int i=0;i字符串是字符的集合(16位无符号)。因此,如果要将负数转换为字符串,它们将在转换过程中丢失。尝试在两种转换中指定一个8位字符集。例如ISO-8859-1。您的字节数组必须有一些编码。如果有负值,则编码不能是ASCII。一旦您弄清楚了这一点,就可以将一组字节转换为字符串字符串使用:
byte[] bytes = {...}
String str = new String(bytes, StandardCharsets.UTF_8); // for UTF-8 encoding
您可以使用一系列编码,请查看中支持的编码。使用新字符串(按原文)
并使用getBytes()
转换回字节[]
不能保证两个字节[]
的值相等。这是由于调用StringCoding.encode(…)
将字符串
编码为Charset.defaultCharset()
。在编码过程中,编码器可能会选择替换未知字符并进行其他更改。因此,使用String.getBytes()
可能不会返回与您最初传递给构造函数相同的数组。根本问题是(我认为)您无意中使用了以下字符集:
bytes != encode(decode(bytes))
在某些情况下,UTF-8就是此类字符集的一个示例。具体而言,某些字节序列在UTF-8中是无效的编码。如果UTF-8解码器遇到这些序列中的一个,则可能会丢弃有问题的字节,或将其解码为“无此类字符”的Unicode码点。当然,当您尝试将字符编码为字节时,结果会有所不同
解决办法是:
明确说明您正在使用的字符编码;即使用字符串构造函数和带有显式字符集的String.toByteArray
方法
为字节数据使用正确的字符集…或者选择一个字符集(如“Latin-1”),其中所有字节序列都映射到有效的Unicode字符
如果您的字节(实际上)是二进制数据,并且您希望能够通过“基于文本”的通道传输/接收它们,请使用类似Base64编码的方法……这是为此目的而设计的
byte[]
和String
之间的“正确转换”是为了明确说明要使用的编码。如果以byte[]
开头,而实际上它不包含文本数据,则不存在“正确转换”。String
s表示文本,byte[]
适用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非您必须这样做
如果您确实必须使用字符串
来保存二进制数据,那么最安全的方法就是使用编码。我们只需要用数组构造一个新的字符串
:
结果字符串的字节因使用的字符集而异。调用string#getBytes()时,新字符串(字节)和新字符串(字节,charset.forName(“utf-8”))以及新字符串(字节,charset.forName(“utf-16”))都将具有不同的字节数组(取决于默认字符集)为什么会出现问题:有人已经指定:
如果以字节[]开头,而实际上它不包含文本数据,那么就没有“适当的转换”。字符串用于文本,字节[]用于二进制数据,唯一真正明智的做法是避免在它们之间进行转换,除非您必须这样做
当我试图从pdf文件创建byte[]并将其转换为字符串,然后将字符串作为输入并转换回文件时,我发现了这个问题。
因此,请确保您的编码和解码逻辑与我的相同。我将字节[]显式编码为Base64,并对其进行解码以再次创建文件
用例:
由于某些限制,我试图在请求(POST)
中发送字节[]
,过程如下:
// 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);
PDF文件>>Base64.encodeBase64(字节[])>>字符串>>发送请求(POST)>>接收字符串>>Base64.decodeBase64(字节[])>>创建二进制文件
试试这个,这个对我有用。
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();
}
这对我来说很好:
String cd="Holding some value";
从字符串转换为字节[]:
byte[] cookie = new sun.misc.BASE64Decoder().decodeBuffer(cd);
从字节[]转换为字符串:
cd = new sun.misc.BASE64Encoder().encode(cookie);
javax.xml.bind.DatatypeConverter
应该执行以下操作:
byte [] b = javax.xml.bind.DatatypeConverter.parseHexBinary("E62DB");
String s = javax.xml.bind.DatatypeConverter.printHexBinary(b);
我使用以下方法成功地将字节数组转换为字符串:
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();
}
公共静态字符串byteArrayToString(字节[]数据){
字符串响应=Arrays.toString(数据);
String[]byteValues=response.substring(1,response.length()-1);
byte[]bytes=新字节[byteValues.length];
对于(int i=0,len=bytes.length;i使用ByteArrayInputStream
从String
读取字节,并用BufferedReader
将其包装,后者是字符流,而不是将字节数据转换为字符串的字节流
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();
}
}
}
输出为:
萨哈尔是个好孩子
我确实注意到了一些答案中没有的东西。你可以将字节数组中的每个字节转换为字符,然后将它们放入一个字符数组。然后字符串就是cbuf是字符数组的地方。要转换回去,通过将每个字符转换为字节的字符串循环,放入一个字节数组,这个字节数组将与e首先
new String(cbuf)
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);
}
}
公共类StringByTearTest{
公共静态void main(字符串[]args){
//把他想要的字节数组放进去
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();
}
}
}
new String(cbuf)
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);
}
}
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();
}
// 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);
InputStream is = new FileInputStream("/home/kalt/Desktop/SUDIS/READY/ds.bin");
byte[] bytes = IOUtils.toByteArray(is);
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);
}
new String(bytes, "UTF-8")
new String(bytes, StandardCharsets.UTF_8)
"test".getBytes(StandardCharsets.UTF_8)
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();
}
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}