Konvertera sträng till Byte Array och Reverse i Java

1. Introduktion

Vi behöver ofta konvertera mellan sträng- och byte- array i Java. I denna handledning kommer vi att undersöka dessa operationer i detalj.

Först tittar vi på olika sätt att konvertera en sträng till en byte- array. Sedan ska vi titta på liknande operationer i omvänd ordning.

2. Konvertera sträng till Byte Array

En sträng lagras som en uppsättning Unicode-tecken i Java. För att konvertera den till en byte- array översätter vi sekvensen av tecken till en sekvens av byte. För den här översättningen använder vi en instans av Charset . Denna klass specificerar en mappning mellan en sekvens av char s och en sekvens av byte s .

Vi hänvisar till ovanstående process som kodning .

Vi kan koda en sträng i en byte- array i Java på flera sätt. Låt oss titta på var och en av dem i detalj med exempel.

2.1. Använda String.getBytes ()

Den String klassen erbjuder tre belastade getBytes metoder för att koda en sträng in i en byte array :

  • getBytes () - kodar med hjälp av plattformens standardteckenuppsättning
  • getBytes (String charsetName) - kodar med namnet charset
  • getBytes (Charset charset) - kodar med den medföljande charset

För det första, låt oss koda en sträng med plattformens standardteckenuppsättning:

String inputString = "Hello World!"; byte[] byteArrray = inputString.getBytes();

Ovanstående metod är plattformsberoende eftersom den använder plattformens standardteckenuppsättning. Vi kan få den här charset genom att ringa Charset.defaultCharset () .

För det andra, låt oss koda en sträng med ett namngivet teckenuppsättning:

@Test public void whenGetBytesWithNamedCharset_thenOK() throws UnsupportedEncodingException { String inputString = "Hello World!"; String charsetName = "IBM01140"; byte[] byteArrray = inputString.getBytes("IBM01140"); assertArrayEquals( new byte[] { -56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90 }, byteArrray); }

Den här metoden kastar UnsupportedEncodingException om den namngivna teckenuppsättningen inte stöds.

Beteendet för de två ovanstående versionerna är odefinierat om ingången innehåller tecken som inte stöds av teckenuppsättningen. Däremot använder den tredje versionen charsets standardbyte-byte-array för att koda ingång som inte stöds.

Därefter låt oss kalla den tredje versionen av de getBytes () metod och passerar en instans av Teckenuppsättning:

@Test public void whenGetBytesWithCharset_thenOK() { String inputString = "Hello ਸੰਸਾਰ!"; Charset charset = Charset.forName("ASCII"); byte[] byteArrray = inputString.getBytes(charset); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33 }, byteArrray); }

Här använder vi fabriksmetoden Charset.forName för att få en instans av Charset . Den här metoden ger ett runtime-undantag om namnet på den begärda teckenuppsättningen är ogiltig. Det ger också ett undantag för körning om teckenuppsättningen stöds i den aktuella JVM.

Men vissa teckenuppsättningar är garanterat tillgängliga på alla Java-plattformar. Den StandardCharsets klassen definierar konstanter för dessa teckenuppsättningar.

Slutligen, låt oss koda med en av de vanliga teckenuppsättningarna:

@Test public void whenGetBytesWithStandardCharset_thenOK() { String inputString = "Hello World!"; Charset charset = StandardCharsets.UTF_16; byte[] byteArrray = inputString.getBytes(charset); assertArrayEquals( new byte[] { -2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33 }, byteArrray); }

Således slutför vi granskningen av de olika versionerna av getBytes . Låt oss sedan titta på metoden som tillhandahålls av Charset själv.

2.2. Använda Charset.encode ()

Den Charset klass ger koda () , en bekväm metod som kodar Unicode-tecken till bitgrupper. Den här metoden ersätter alltid ogiltiga inmatningar och tecken som inte kan omvandlas med hjälp av teckenuppsättningens standardbytesgrupp.

Låt oss använda kodningsmetoden för att konvertera en sträng till en byte- array:

@Test public void whenEncodeWithCharset_thenOK() { String inputString = "Hello ਸੰਸਾਰ!"; Charset charset = StandardCharsets.US_ASCII; byte[] byteArrray = charset.encode(inputString).array(); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33 }, byteArrray); }

Som vi kan se ovan, har inte stöds tecken ersatts med teckenuppsättning standard byte byte 63.

De metoder som hittills har använts använder klassen CharsetEncoder internt för att utföra kodning. Låt oss undersöka den här klassen i nästa avsnitt.

2.3. CharsetEncoder

CharsetEncoder förvandlar Unicode-tecken till en sekvens av byte för en given charset . Dessutom ger den finkornig kontroll över kodningsprocessen .

Låt oss använda den här klassen för att konvertera en sträng till en byte- array:

@Test public void whenUsingCharsetEncoder_thenOK() throws CharacterCodingException { String inputString = "Hello ਸੰਸਾਰ!"; CharsetEncoder encoder = StandardCharsets.US_ASCII.newEncoder(); encoder.onMalformedInput(CodingErrorAction.IGNORE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(new byte[] { 0 }); byte[] byteArrray = encoder.encode(CharBuffer.wrap(inputString)) .array(); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 33 }, byteArrray); }

Här skapar vi en instans av CharsetEncoder genom att anropa metoden newEncoder på ett Charset- objekt.

Därefter vi specificera åtgärder för felförhållanden genom att anropa onMalformedInput () och onUnmappableCharacter () metoder . Vi kan ange följande åtgärder:

  • IGNORE - släpp den felaktiga inmatningen
  • Byt ut - byt ut den felaktiga ingången
  • RAPPORT - rapportera felet genom att returnera ett CoderResult- objekt eller kasta ett CharacterCodingException

Dessutom använder vi metoden replateWith () för att specificera byte- arrayen.

Således slutför vi granskningen av olika metoder för att konvertera en sträng till en byte-array. Låt oss titta på omvänd operation.

3. Konvertera byte-array till sträng

Vi hänvisar till processen att konvertera en byte- array till en sträng som avkodning . I likhet med kodning kräver denna process en Charset .

Vi kan dock inte bara använda någon charset för avkodning av en byte-array. Vi borde använda charset som användes för att koda strängen i byte- arrayen .

Vi kan konvertera en byte-array till en sträng på många sätt. Låt oss undersöka var och en av dem i detalj.

3.1. Använda String Constructor

The String class has few constructors which take a byte array as input. They are all similar to the getBytes method but work in reverse.

First, let's convert a byte array to String using the platform's default charset:

@Test public void whenStringConstructorWithDefaultCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray); assertNotNull(string); }

Note that we don't assert anything here about the contents of the decoded string. This is because it may decode to something different, depending on the platform's default charset.

For this reason, we should generally avoid this method.

Secondly, let's use a named charset for decoding:

@Test public void whenStringConstructorWithNamedCharset_thenOK() throws UnsupportedEncodingException { String charsetName = "IBM01140"; byte[] byteArrray = { -56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90 }; String string = new String(byteArrray, charsetName); assertEquals("Hello World!", string); }

This method throws an exception if the named charset is not available on the JVM.

Thirdly, let's use a Charset object to do decoding:

@Test public void whenStringConstructorWithCharSet_thenOK() { Charset charset = Charset.forName("UTF-8"); byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

Finally, let's use a standard Charset for the same:

@Test public void whenStringConstructorWithStandardCharSet_thenOK() { Charset charset = StandardCharsets.UTF_16; byte[] byteArrray = { -2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

So far, we have converted a byte array into a String using the constructor. Let's now look into the other approaches.

3.2. Using Charset.decode()

The Charset class provides the decode() method that converts a ByteBuffer to String:

@Test public void whenDecodeWithCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33 }; Charset charset = StandardCharsets.US_ASCII; String string = charset.decode(ByteBuffer.wrap(byteArrray)) .toString(); assertEquals("Hello �orl�!", string); }

Here, the invalid input is replaced with the default replacement character for the charset.

3.3. CharsetDecoder

Alla tidigare metoder för avkodning internt använder klassen CharsetDecoder . Vi kan använda den här klassen direkt för finkornig kontroll av avkodningsprocessen :

@Test public void whenUsingCharsetDecoder_thenOK() throws CharacterCodingException { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33 }; CharsetDecoder decoder = StandardCharsets.US_ASCII.newDecoder(); decoder.onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith("?"); String string = decoder.decode(ByteBuffer.wrap(byteArrray)) .toString(); assertEquals("Hello ?orl?!", string); }

Här ersätter vi ogiltiga ingångar och tecken som inte stöds med “?”.

Om vi ​​vill informeras i händelse av ogiltiga ingångar kan vi ändra avkodaren som:

decoder.onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT)

4. Slutsats

I den här artikeln undersökte vi flera sätt att konvertera sträng till en byte-array och omvänd. Vi bör välja lämplig metod baserat på indata och den kontrollnivå som krävs för ogiltiga ingångar.

Som vanligt kan hela källkoden hittas på GitHub.