2017-04-04 70 views
2

我尝试读取“bytefile”中的字节,将其更改为String并将其存储为“stringfile”。下面的代码是我的表现。将字节转换为字节到字节

PrintWriter writer = new PrintWriter(new FileOutputStream(new File("stringfile"), true)); 
    RandomAccessFile file = new RandomAccessFile("bytefile", "r"); 
    byte[] b = new byte[(int)file.length()]; 
    file.readFully(b); 
    String str = new String(b, StandardCharsets.UTF_8); 
    writer.write(str); 
    writer.close(); 

然后我尝试将“stringfile”中的字符串转换为字节并存储在“newbytefile”中。但是,结果并不符合我的预期。

String charset = "UTF-8"; 
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("stringfile"), charset)); 
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("newbytefile"), charset)); 
    String line; 
    while ((line = reader.readLine()) != null){ 
     writer.println(line.getBytes()); 
    } 
    reader.close(); 
    writer.close(); 

“bytefile” 中的模式是这样的:

<9e>zgóoG^[email protected]<81>^B*É^X¿uú<9b>^@ 

在 “stringfile” 的模式是这样的:

�zg�oG^[email protected]�^B*�^X�u��^@�� V� 

然而,在“newbytefile模式“是这样的:

[[email protected] 

如何将“stringfile”中的字符串转换为与“bytefile”中的原始patten相同的字节?

+0

如何将数组转换为字符串:http://stackoverflow.com/questions/409784/whats-the-simplest-way- to-print-a-java-array –

+0

'writer.println(line.getBytes());'实际调用'println(Object)',然后调用'Object'的默认'toString'。 – Berger

回答

2

问题是:PrintWriter没有写入byte []数组的方法。

所以,当你调用println(getBytes()) ...编译器试图找到匹配的重载方法。它会找到println(Object)(因为:最后,任何java数组都是也是的一个对象)。

你可以看到,使用javap的反汇编:

invokevirtual#22 // java的方法/ IO/PrintWriter.println:(Ljava /郎/对象;)V

和内该方法在传入对象上调用toString()。当你在一个字节数组上调用toString()时,你会得到一个类似于“[B ....”的结果 - 见here。换句话说:由于重载,你不是打印字节数组本身,而是打印字节数组本身的默认字符串表示形式。

+0

'println(String)'只有在你传递一个String引用时才被调用。 –

+1

它使用println(Object)方法隐式调用数组上的toString方法,并给它指定数组的地址 –

+0

只需要对Java经验较少的其他用户完全清楚,您是否可以移动“编译器决定使用println对象)“位于它如何转换为字符串的解释之上。只是为了让阅读答案的其他人没有看到它被转换为字符串,并想知道为什么它不使用println(String)重载? –

0

有些事情你应该注意:

  • 文件始终字节流。您可以通过假定特定的编码来假装它们是文本。
  • 您的第一个示例不使用特定的编码来编写PrintWriter,因此您使用的是默认设置,您必须使用它来读取该文件。
  • 您已经知道如何使用字符编码进行读/写,编码和解码,您只需要一致地执行。
  • Object.toString()打印对象的类型,'@'和标识哈希码。 byte []不会覆盖这个方法,这就是为什么你将它看作你所做的代码的原因。
-1

你是在正确的轨道上,你仍然需要通过构建一个与正确的参数字节字符串数组转换:

new String(line.getBytes(), "UTF-8"); 

请记住,有转换的多种方式字节数组转换为String。

0

你也可能发现你的输入数据导致了一个问题:它不能正确地编码成一个字符串。

如果你运行:

package au.com.redbarn.stackoverflow.convert_byte_to_string_to_byte; 

import java.nio.charset.StandardCharsets; 

public class NoFiles { 

    public static void main(String[] args) { 

     byte[] byteIn = {60, 57, 101, 62, 122, 103, -13, 111, 71, 94, 80, 36, 64, 48, 60, 56, 49, 62, 94, 66, 42, -55, 94, 88, -65, 117, -6, 60, 57, 98, 62, 94, 64}; 
     String s = new String(byteIn, StandardCharsets.UTF_8); 
     byte[] byteOut = s.getBytes(StandardCharsets.UTF_8); 
     System.out.println(byteOut); 
    } 
} 

byteIn = byteOut

也许你知道会转换为字符串正确的字节数组开始!你究竟想要做什么?

前提是你的字节数组可以适当转换,这将工作:

package au.com.redbarn.stackoverflow.convert_byte_to_string_to_byte; 

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.nio.charset.StandardCharsets; 
import java.nio.file.FileSystems; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.util.List; 

public class ConvertByteToStringToByte { 

    public static void main(String[] args) { 

     try { 
      // Read bytes, write String. 
      byte[] b = Files.readAllBytes(FileSystems.getDefault().getPath("bytefile-in")); 
      String strOut = new String(b, StandardCharsets.UTF_8); 

      try (PrintWriter pw = new PrintWriter("stringfile")){ 
       pw.println(strOut); 
      } 
      catch (IOException e) { 
       throw (e); 
      } 

      // Read String, write bytes. 
      List<String> strsIn = Files.readAllLines(FileSystems.getDefault().getPath("stringfile")); 

      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

      for (String strIn : strsIn) { 
       baos.write(strIn.getBytes(StandardCharsets.UTF_8)); 
      } 

      Files.write(Paths.get("bytefile-out"), baos.toByteArray());   
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
}