如何将字节数组转换为字符串,反之亦然
我必须在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);
我被困在这个问题。
byte[]
和String
之间的“正确转换”是明确指定要使用的编码。 如果以byte[]
开头,实际上并不包含文本数据,则不存在 “正确的转换”。 String
s用于文本, byte[]
用于二进制数据,唯一真正合理的做法是避免在它们之间转换,除非您绝对必须。
如果你真的必须使用一个String
来保存二进制数据,那么最安全的方法是使用Base64编码。
你的字节数组必须有一些编码。 如果您有负值,则编码不能为ASCII。 一旦你弄清楚了,你可以使用以下命令将一组字节转换为一个字符串:
byte[] bytes = {...} String str = new String(bytes, "UTF-8"); // for UTF-8 encoding
有一堆你可以使用的编码,查看Sun javadoc中的Charset类。
根本问题是(我认为)你不知不觉地使用一个字符集为:
bytes != encode(decode(bytes))
在某些情况下。 UTF-8就是这样一个字符集的一个例子。 具体来说,某些字节序列在UTF-8中不是有效的编码。 如果UTF-8解码器遇到这些序列之一,则可能会丢弃违规字节或将其解码为“没有这样的字符”的Unicode码点。 当然,当你试图将字符编码为字节时,结果将会不同。
解决方案是:
- 明确你正在使用的字符编码; 即使用显式字符集使用String构造函数和
String.toByteArray
方法。 - 使用正确的字符集为您的字节数据…或者一个(如所有字节序列映射到有效的Unicode字符的“Latin-1”。
- 如果你的字节是(真正的)二进制数据,你希望能够通过“基于文本”的通道发送/接收它们,请使用像Base64编码… 这是专门为此目的而设计的 。
我们只需要用数组构造一个新的String
: http : //www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/
String s = new String(bytes);
结果字符串的字节取决于您使用的字符集。 新的字符串(字节)和新的字符串(字节,Charset.forName(“UTF-8”))和新的字符串(字节,Charset.forName(“utf-16”))都将有不同的字节数组, getBytes()(取决于默认的字符集)
使用new String(byOriginal)并使用getBytes()转换回byte []不能保证具有相同值的两个byte []。 这是由于对StringCoding.encode(..)的调用,它将字符串编码为Charset.defaultCharset() 。 在此编码期间,编码器可能会选择替换未知字符并进行其他更改。 因此,使用String.getBytes()可能不会像最初传递给构造函数那样返回一个相等的数组。
这对我来说很好:
String cd="Holding some value";
从字符串转换为字节[]:
byte[] cookie = new sun.misc.BASE64Decoder().decodeBuffer(cd);
从字节[]转换为字符串:
cd = new sun.misc.BASE64Encoder().encode(cookie);
为什么是这样的问题:正如已经指定的人: 如果你从一个字节[]开始,而实际上并不包含文本数据,那么就没有“正确的转换”。 字符串用于文本,byte []用于二进制数据,唯一真正合理的做法是避免在它们之间进行转换,除非您绝对必须。
我正在观察这个问题,当我试图从PDF文件创建byte [],然后将其转换为字符串,然后将字符串作为输入并转换回文件。
所以确保你的编码和解码逻辑和我一样。 我明确地将byte []编码为Base64,并对其进行解码以再次创建文件。
用例:由于一些限制,我试图在request(POST)
发送byte[]
,过程如下:
PDF文件>> Base64.encodeBase64(byte [])>> String >>发送请求(POST)>>接收字符串>> Base64.decodeBase64(byte [])>> create binary
试试这个,这对我工作..
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(); }
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; }
我注意到了一些没有任何答案的东西。 您可以将字节数组中的每个字节转换为字符,并将它们放入字符数组中。 那么这个字符串是
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); } }
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(); }
下面是将字节数组转换为字符串的几种方法。 我测试了他们的工作。
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(); }
尝试在两次转换中指定一个8位字符集。 例如ISO-8859-1。
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); }
使用ByteArrayInputStream
从String
读取字节,并使用Char Stream(而不是Byte Stream)的BufferedReader
(将字节数据转换为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(); } } }
输出是:
萨哈尔是个好孩子
这里的工作代码。
// 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);
一个字符串是char的集合(16位无符号)。 所以,如果你打算把负数转换成一个字符串,他们将会在翻译中迷失方向。
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); } }
使用Base64解决您的问题。它太容易使用。 http://iharder.sourceforge.net/current/java/base64/