2016-04-20 17 views
2

Ich führe den folgenden Code aus und bekomme ein anderes Ergebnis von "some_string" .getBytes() abhängig davon, ob ich in Windows oder Unix bin. Das Problem tritt mit einer beliebigen Zeichenkette (habe ich versucht, ein sehr einfaches ABC und gleiche Problem.Warum funktioniert "STRING" .getBytes() je nach Betriebssystem

die Unterschiede Siehe unten in der Konsole gedruckt.

Der folgende Code ist gut getestet mit Java 7. Wenn Sie es ganz kopieren

Siehe auch den Unterschied in Hexadezimal in den beiden folgenden Bildern Die ersten zwei Bilder zeigt die Datei erstellt in Windows Sie können die hexadezimalen Werte mit ANSI und EBCDIC jeweils sehen Das dritte Bild, das schwarze Bild , ist von Unix.Sie können die hexadezimale (-C-Option) und das Zeichen lesen, in dem ich glaube, dass es EBCDIC ist

Meine Frage ist also: Warum funktioniert ein solcher Code anders, da ich in beiden Fällen nur Java 7 verwende? Sollte ich irgendein spezifisches Eigentum irgendwo überprüfen? Vielleicht bekommt Java in Windows ein bestimmtes Standardformat und in Unix ein anderes. Wenn ja, welche Immobilie muss ich prüfen oder einrichten?

enter image description here

Unix-Konsole:

$ ./java -cp /usr/test.jar test.mainframe.read.test.TestGetBytes 
H = 76 - L 
< wasn't found 

Windows-Konsole:

H = 60 - < 
H1 = 69 - E 
H2 = 79 - O 
H3 = 77 - M 
H4 = 62 - > 
End of Message found 

Der gesamte Code:

package test.mainframe.read.test; 

import java.util.ArrayList; 

public class TestGetBytes { 

     public static void main(String[] args) { 
       try { 
        ArrayList ipmMessage = new ArrayList(); 
        ipmMessage.add(newLine()); 

        //Windows Path 
        writeMessage("C:/temp/test_bytes.ipm", ipmMessage); 
        reformatFile("C:/temp/test_bytes.ipm"); 
        //Unix Path 
        //writeMessage("/usr/temp/test_bytes.ipm", ipmMessage); 
        //reformatFile("/usr/temp/test_bytes.ipm"); 
       } catch (Exception e) { 

        System.out.println(e.getMessage()); 
       } 
     } 

     public static byte[] newLine() { 
       return "<EOM>".getBytes(); 
     } 

     public static void writeMessage(String fileName, ArrayList ipmMessage) 
        throws java.io.FileNotFoundException, java.io.IOException { 

       java.io.DataOutputStream dos = new java.io.DataOutputStream(
          new java.io.FileOutputStream(fileName, true)); 
       for (int i = 0; i < ipmMessage.size(); i++) { 
        try { 
          int[] intValues = (int[]) ipmMessage.get(i); 
          for (int j = 0; j < intValues.length; j++) { 
            dos.write(intValues[j]); 
          } 
        } catch (ClassCastException e) { 
          byte[] byteValues = (byte[]) ipmMessage.get(i); 
          dos.write(byteValues); 
        } 
       } 
       dos.flush(); 
       dos.close(); 

     } 

     // reformat to U1014 
     public static void reformatFile(String filename) 
        throws java.io.FileNotFoundException, java.io.IOException { 
       java.io.FileInputStream fis = new java.io.FileInputStream(filename); 
       java.io.DataInputStream br = new java.io.DataInputStream(fis); 

       int h = br.read(); 
       System.out.println("H = " + h + " - " + (char)h); 

       if ((char) h == '<') {// Check for <EOM> 

        int h1 = br.read(); 
        System.out.println("H1 = " + h1 + " - " + (char)h1); 
        int h2 = br.read(); 
        System.out.println("H2 = " + h2 + " - " + (char)h2); 
        int h3 = br.read(); 
        System.out.println("H3 = " + h3 + " - " + (char)h3); 
        int h4 = br.read(); 
        System.out.println("H4 = " + h4 + " - " + (char)h4); 
        if ((char) h1 == 'E' && (char) h2 == 'O' && (char) h3 == 'M' 
            && (char) h4 == '>') { 
          System.out.println("End of Message found"); 
        } 
        else{ 
          System.out.println("EOM not found but < was found"); 
        } 
       } 
       else{ 
        System.out.println("< wasn't found"); 
       } 
     } 
} 

Antwort

3

Sie sind nicht ein charset angeben, wenn Aufruf getBytes(), so dass es den Standard-Zeichensatz der zugrunde liegenden Plattform (oder von Java selbst, wenn angegeben, wenn Java gestartet wird) verwendet. Dies ist in den String documentation angegeben:

public byte [] getBytes()

Codiert diesen String in eine Folge von Bytes der Standard-Zeichensatz der Plattform, um das Ergebnis in einen neuen Byte-Array zu speichern.

getBytes() verfügt über eine überladene Version, in der Sie einen Zeichensatz in Ihrem Code angeben können.

public byte [] getBytes (Charset charset)

Codiert diesen String in eine Folge von Bytes den gegebenen Zeichensatz unter Verwendung von, um das Ergebnis in einen neuen Byte-Array zu speichern.

+2

Unter Windows ist der Standard-Zeichensatz sehr wahrscheinlich cp1252 (oder länderspezifischer Zeichensatz). Viele Linux verwenden UTF08. Auf dem Mainframe vermute ich, dass es EBCDIC –

+1

* wahrscheinlich * cp1252 normalerweise nur in westlichen Ländern gibt. Es gibt viele Ansi-Zeichensätze auf der ganzen Welt und viele Windows-Codepages für sie. Nehmen Sie nicht cp1252 an, seien Sie explizit auf Ihre tatsächlichen Bedürfnisse basierend. –

+0

Danke. Es ist das erste Mal, dass ich mit Mainframe arbeite und ehrlich gesagt muss ich noch nie ein Characting-Set in der Windows-Welt einrichten. Ich habe das Problem nach dem Vorschlag behoben und das ist wirklich die Antwort auf meine Frage.Übrigens, wenn du mir einen Artikel oder eine Frage in diesem Forum vorschlagen kannst, um zu lesen, welcher Zeichensatz wirklich bedeutet, werde ich dankbar sein. Im Mainframe arbeite ich, der Zeichensatz ist IBM1047 (ich habe dies beim Drucken von java.nio.charset.Charset.defaultcharset bekommen). Das Problem wurde behoben, indem org.apache.commons.io.Charsets.UTF_8 in getBytes() übergeben wurde. Ich fand es seltsam, dass ich in java.nio nicht dieselbe Konstante gefunden habe. –

Verwandte Themen