2017-04-04 182 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(); 
     } 
    } 
}