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

我必须在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码点。 当然,当你试图将字符编码为字节时,结果将会不同。

解决方案是:

  1. 明确你正在使用的字符编码; 即使用显式字符集使用String构造函数和String.toByteArray方法。
  2. 使用正确的字符集为您的字节数据…或者一个(如所有字节序列映射到有效的Unicode字符的“Latin-1”。
  3. 如果你的字节是(真正的)二进制数据,你希望能够通过“基于文本”的通道发送/接收它们,请使用像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); } 

使用ByteArrayInputStreamString读取字节,并使用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/