Byte -> String -> Byte verlustfrei

  • Themenstarter Themenstarter valkyrie
  • Beginndatum Beginndatum
V

valkyrie

Gast
Hi,
ich will mit [/code]new String(byte[]);[/code] ein Bytearray in einen String umwandeln. Die Bytes beinhalten allerdings auch Daten die nicht ASCII konform sind. Wenn ich den String danach in einen Hex-String umwandeln will, kommt nicht das ursprüngliche Byte raus, sondern die hex-Darstellung des UTF-8 Zeichens (zb: 0xFF84).
Gibt es eine Möglichkeit, in der die bytes wieder "verlustfrei" hergestellt werden können?
 
einfach das ursprüngliche Byte-Array speichern?

Hatte ich versucht mit einem ByteBuffer und mit einem byte[]. Zurück kam immer 0x00 für jeden Wert.

Hier ist mal der komplette Code. Vielleicht fällt euch ja eine Lösung ein, auf die ich bisher nicht gekommen bin.
Java:
	public void run()
	{
		Thread me = Thread.currentThread();
		StringBuffer buffer = new StringBuffer();
		
	    while (timer == me) {
	    	int i;
			/*
	        try {
	            Thread.currentThread().sleep(200);
	        } catch (InterruptedException e) { }
	        */
	        if (gtp != null){//alt: if ( (gtp != null) && ((i = gtp.available()) > 0)){
	        
                while((i = gtp.available()) > 0)
                {
                    //String received = new String(gtp.receive());

                    byte[] recBytes = gtp.receive();								// receive incoming data 
                    buffer.append(new String(recBytes));							// write received incoming data to the buffer 
                    int end = buffer.indexOf("\n\r",0);								// search for the next "\n\r" and save the index to end
                    String received = buffer.substring(0,end+1);					// the string between buffer[0] and buffer[end+1] is saved to received for further processing
                    
					//byte[] receivedBytes = Arrays.copyOfRange(recBytes, 0, end+2);
					
					 
					/*
					for (int k = 0; k < end+2; k++)
					{
						receivedBytes[k] = recBytes[k];
					}*/
					
					// allow only responses > 0
                    if(received.length() != 0)
                    {
                    	// delete current response from buffer
                        StringBuffer tempBuffer = new StringBuffer();
                       
                        tempBuffer.append(buffer.substring(end+2,buffer.length()));	
                        buffer = tempBuffer;
                        
						// processing of a GET_CONF-command response
                        if(received.startsWith("GET_CONF_OKAY_"))
                        {                   
                            String payload = received.substring("GET_CONF_OKAY_".length(), received.length()-1); // copy payload of frame to a new string
                            String output = "GET_CONF_OKAY_( ";						// generate prelude of GET_CONF_OKAY_ frame							

                            for(int j = 0; j < payload.length(); j++)
                            {
                                String temp = Integer.toHexString(payload.charAt(j) & 0xFF);	// convert char to hex string   byteBuffer[j+"GET_CONF_OKAY_".length()]
                                String pad = "";									// default padding ist ""
                                if(temp.length() < 2)
                                {
                                    pad = "0";										// if temp has only one digit, pad a '0' on left side
                                }//(temp.length() < 2)
                                output += pad + temp + " ";							// generate output for a hex value
                            }//for(int j = 0; j < payload.length(); j++)
                            output += ")\n\r";										// complete GET_CONF_OKAY_ frame
                            textArea.append(output);                                // print output string in text area
                            textArea.setCaretPosition(textArea.getText().length()); // view always last row in text area
                        }//if(received.startsWith("GET_CONF_OKAY_"))
                        
                        // for every uC response of a command, except the GET_CONFIG command
                        else
                        {
                            textArea.append("--");									// to display line breaks
                            textArea.append(received);                              // print received string in text area
                            textArea.setCaretPosition(textArea.getText().length()); // view always last row in text area
                        }//else
					}//if(received.length() != 0)
				}//while((i = gtp.available()) > 0)
			}//if(gtp != null)
	    }//while(timer == me)
	}//public void run()
Eigentlich werden in dieser Methode nur Daten empfangen und dann ausgewertet. An den GET_CONF_OKAY_ Teil folgen angehängt die bytes die ich gerne in hex darstellen würde. Deshalb da die gesonderte Behandlung.
 
Hi,
hab den Code noch etwas überarbeitet. Hab mal zusätzlich zu der Stringbehandlung noch eine Möglichkeit eingebaut die bytes direkt zu speichern. Funktioniert leider nicht ganz im Moment.
(Die Datenpakete die in die Methode kommen sind oft zerstückelt, deshalb das umständliche puffern)

Über Anregungen wäre ich sehr dankbar.
Java:
	// print received data on text area
	public void run()
	{
		Thread me = Thread.currentThread();
		StringBuffer buffer = new StringBuffer();
		byte[] bbuffer = null;
	    while (timer == me) {
	    	int i;
			/*
	        try {
	            Thread.currentThread().sleep(200);
	        } catch (InterruptedException e) { }
	        */
	        if (gtp != null){//alt: if ( (gtp != null) && ((i = gtp.available()) > 0)){

                while((i = gtp.available()) > 0)
                {
                    //String received = new String(gtp.receive());

                    byte[] rec = gtp.receive();							// receive incoming data
                    
                    buffer.append(new String(rec));                     // write received incoming data to the buffer
                    
                	textArea.append(new String(rec));
                    
                    byte[] result = new byte[rec.length + bbuffer.length];		// merge bbuffer and rec together keeping the right order
                    for (int k = 0; k < bbuffer.length; k++) 
                    {
                        result[k] = bbuffer[k];									// copy bbuffer to result[]
                    }
                    for (int l = 0; l < rec.length; l++)
                    {
                    	result[l+bbuffer.length] = rec[l];						// copy rec to result[]
                    }
                    bbuffer = result;
                    
                    textArea.append(new String(result));
                    
                    int end = buffer.indexOf("\n\r",0);								// search for the next "\n\r" and save the index to end
                    String received = buffer.substring(0,end+1);					// the string between buffer[0] and buffer[end+1] is saved to received for further processing

					// allow only responses > 0
                    if(received.length() > 0)
                    {
                    	// delete current response from buffer
                        StringBuffer tempBuffer = new StringBuffer();
                        tempBuffer.append(buffer.substring(end+2,buffer.length()));
                        buffer = tempBuffer;
						
						// delete used response from bbuffer
						byte[] btemp = null;
						for (int m = 0; m < bbuffer.length-end-1; m++)
						{
							btemp[m] = bbuffer[m+end+2];
						}
						bbuffer = btemp;

						// processing of a GET_CONF-command response
                        if(received.startsWith("GET_CONF_OKAY_"))
                        {
                            String payload = received.substring("GET_CONF_OKAY_".length(), received.length()-1); // copy payload of frame to a new string
                            String output = "GET_CONF_OKAY_( ";						// generate prelude of GET_CONF_OKAY_ frame

                            for(int j = 0; j < payload.length(); j++)
                            {
                                String temp = Integer.toHexString(result[j+13] & 0xFF);	// convert char to hex string
                                String pad = "";									// default padding ist ""
                                if(temp.length() < 2)
                                {
                                    pad = "0";										// if temp has only one digit, pad a '0' on left side
                                }//(temp.length() < 2)
                                output += pad + temp + " ";							// generate output for a hex value
                            }//for(int j = 0; j < payload.length(); j++)
                            output += ")\n\r";										// complete GET_CONF_OKAY_ frame
                            textArea.append(output);                                // print output string in text area
                            textArea.setCaretPosition(textArea.getText().length()); // view always last row in text area
                        }//if(received.startsWith("GET_CONF_OKAY_"))

                        // for every uC response of a command, except the GET_CONFIG command
                        else
                        {
                            textArea.append("--");									// to display line breaks
                            textArea.append(received);                              // print received string in text area
                            textArea.setCaretPosition(textArea.getText().length()); // view always last row in text area
                        }//else
					}//if(received.length() != 0)
				}//while((i = gtp.available()) > 0)
			}//if(gtp != null)
	    }//while(timer == me)
	}//public void run()
}
 
was ist denn nochmal das Thema überhaupt?
neben meinem ignorierten Vorschlag war die Rückfrage, die bytes direkt zu verarbeiten, ohne String,
was spricht dagegen? deine Code-Beispiele haben beide new String(bytes) sowie viel unbekanntes (was ist gtp?),
der Code sagt wenig aus, sonst hast du auch wenig geschrieben


> buffer.indexOf("\n\r",0);
zeigt zumindest, dass du die bytes anscheinend als Text, als Zeichenfolge interpretieren willst,
das ist schon bisschen was anderes als nur 'bytes temporär in String damit am Ende wieder bytes raus kommen'

für solche Such-Aktionen musst du die bytes tatsächlich in einen String umwandeln,
String-Konstruktor geht dafür vielleicht, aber dann als zusätzlichen Parameter das Encoding,
das Encoding kann man auch einem Reader auf einem InputStream anvertrauen,

allgemein bekannt?
Java best Practices - Zeichensatz & Character Encoding
 
Wenn non-ASCII-Zeichen genutzt werden, dann muss man auch den Zeichensatz angeben 😉
Denn sonst wird von dem Standard-Java-Zeichensatz UTF-16 ausgegangen.

wie wandelt man denn ein byte so um. Kann ich da den Standard mit angeben, zb so:
Java:
byte[] rec = ...
new String(rec, "ISO8859_1 "))
 
was ist denn nochmal das Thema überhaupt?

gtp ist eine Instanz einer TCP/IP-Klasse. Mit der receive()-Methode bekommt man ankommende Daten.
In meinem Fall werden die Daten von einem Mikrocontroller verschickt. Größtenteils handelt es sich bei diesen Daten um ganz normale Zeichen (strings). Bei einem Frame, der vom Mikrocontroller verschickt wird, sind an den Rumpf aus char-Zeichen noch binäre Daten angehängt. Da diese binären Daten nicht einfach so dargestellt werden können, will ich diese in hex-Darstellung umwandeln.
Am liebsten wäre es mir alle bytes als string zu behandeln, so kann ich einfach nach bestimmten Zeichen suchen, die das Ende einer Nachricht anzeigen.
 
Base64 Kodierung? 😉

einen base64 kodierten string kann ich nicht so ohne weiteres weiterverarbeiten. Der größte Teil der Daten sollte ich als normalen string haben.

mit einem inputstreamreader kann man den richtigen Kodierungsstandard einstellen so wie ich das verstanden habe. Allerdings hab ich keine Erfahrung damit und versteh noch nicht so ganz wie ich das anwenden muss.
 
was kann man da nicht verstehen oder aus den google-Beispielen nicht sehen?
wie man einen Stream oder etwas anders einen Reader benutzt ist komplett Grundlage,
und ansonsten musst du nur das Encoding angeben,

welches das ist kann ich nicht sagen, vielleich paar ausprobieren
Supported Encodings
 
Die Kommentare gefallen mir. 😀
Java:
public boolean getTrue() {
    boolean result = true; // result auf true setzen
    return result; // result zurückgeben
} // Ende getTrue
Dem Quelltext täte auch ein halbes Dutzend Methoden ganz gut. Es geht da ziemlich wüst und durcheinander zur Sache. 😉

Wenn ich den String danach in einen Hex-String umwandeln will, kommt nicht das ursprüngliche Byte raus, sondern die hex-Darstellung des UTF-8 Zeichens (zb: 0xFF84).
Das ist jetzt aber auch nicht allzu verwunderlich, oder? Ein Hex-String mit Hex-Darstellungen enthält idealerweise Hex-Darstellungen.

Wenn non-ASCII-Zeichen genutzt werden, dann muss man auch den Zeichensatz angeben 😉
Denn sonst wird von dem Standard-Java-Zeichensatz UTF-16 ausgegangen.
Es wird die Standardkodierung des Systems verwendet, und die ist „irgend eine“, abhängig vom Betriebssystem und den Einstellungen eines Nutzers. Man kann natürlich kein Byte-Feld nehmen und einfach so in einen String umwandeln, ohne daß man die Kodierung angibt, außer natürlich, man ist von Russischem Roulette angetan. Kann ja auch spannend sein! In Zeile 22 und 24 wird die Pistole jedenfalls an die Schläfe gelegt.
 

Zurück
Oben