如何在JAVA中将String变量转换回byte []

时间:2018-12-03 21:02:26

标签: java

我有以下代码来压缩和解压缩字符串:

public static void main(String[] args) {
    // TODO code application logic here
    String Source = "hello world";
    byte[] a = ZIP(Source);
    System.out.format("answer:");
    System.out.format(a.toString());
    System.out.format("\n");


    byte[] Source2 = a.toString().getBytes();

    System.out.println("\nsource 2:" + Source2.toString() + "\n");

    String b = unZIP(Source2);
    System.out.println("\nunzip answer:");
    System.out.format(b);
    System.out.format("\n");


}

  public static byte[] ZIP(String source) {
      ByteArrayOutputStream bos= new ByteArrayOutputStream(source.length()* 4);

      try {
          GZIPOutputStream outZip= new GZIPOutputStream(bos);
          outZip.write(source.getBytes());
          outZip.flush();
          outZip.close();
      } catch (Exception Ex) {
      }
      return bos.toByteArray();
  }

public static String unZIP(byte[] Source) {
    ByteArrayInputStream bins= new ByteArrayInputStream(Source);
    byte[] buf= new byte[2048];
    StringBuffer rString= new StringBuffer("");
    int len;

    try {
        GZIPInputStream zipit= new GZIPInputStream(bins);
        while ((len = zipit.read(buf)) > 0) {
             rString.append(new String(buf).substring(0, len));
        }
        return rString.toString();
    } catch (Exception Ex) {
       return "";
    }
}

压缩“ Hello World”后,它将变为[B @ 7bdecdec in byte [],并转换为String并显示在屏幕上。但是,如果我尝试使用以下代码将字符串转换回byte []:

 byte[] Source2 = a.toString().getBytes();

变量a的值将变为[B @ 60a1807c,而不是[B @ 7bdecdec]。有人知道如何在JAVA中将byte的String(一个字节的值,但已转换为String)转换回byte []吗?

2 个答案:

答案 0 :(得分:3)

为什么要byte[] Source2 = a.toString().getBytes();

似乎是双重转换;您将byte[]转换为string并转换为byte[].

byte[]到字符串的真正转换是new String(byte[]),希望您处于同一字符集中。

Source2应该是a的精确副本,因此您应该只进行byte[] Source2 = a;

答案 1 :(得分:2)

您的解压缩是错误的,因为您要转换回一个可能采用其他编码(例如UTF-8)的字符串:

public static String unZIP(byte[] source) throws IOException {
  ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length*2);
  try (ByteArrayInputStream in = new ByteArrayInputStream(source);
       GZIPInputStream zis = new GZIPInputStream(in)) {
    byte[] buffer = new buffer[4096];
    for (int n = 0; (n = zis.read(buffer) != 0; ) {
      bos.write(buffer, 0, n);
    }
  }
  return new String(bos.toByteArray(), StandardCharsets.UTF_8);
}

未经测试的该产品将:

  • 将gzip流中的字节存储到ByteArrayOutputStream
  • 尝试使用资源关闭gzip / ByteArrayInputStream
  • 使用UTF-8将整个结果转换为String(您应该始终使用编码,除非极少数情况,否则应使用UTF-8)。

出于两个原因,您不得使用StringBuffer

  • 最重要的一个:对于多字节字符串(例如UTF-8或UTF-16),这将无法正常工作。
  • 第二,StringBuffer已同步:您应尽可能使用StringBuilder(例如:不在此处!)。 StringBuffer应该保留给与多个线程共享StringBuffer的情况,否则就没有用了。

进行了这些更改后,您还需要根据David Conrad的注释来更改ZIP,并且因为unZIP使用UTF-8:

public static byte[] ZIP(String source) throws IOException {
  ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length()* 4);
  try (GZIPOutputStream zip = new GZIPOutputStream(bos)) {
    zip.write(source.getBytes(StandardCharsets.UTF_8));
  }
  return bos.toByteArray();
}

对于主机,打印byte[]将得到默认的toString