InputStream naar String in Kotlin

1. Overzicht

In deze korte tutorial leren we hoe je een InputStream in een Draad.

Kotlin biedt een gemakkelijke manier om de conversie uit te voeren. Er zijn echter nog enkele nuances waarmee u rekening moet houden bij het werken met bronnen. Bovendien behandelen we speciale gevallen, zoals lezen tot een aanslagkarakter.

2. Gebufferde lezer

InputStream is een abstractie rond een geordende stroom bytes. Een onderliggende gegevensbron kan een bestand zijn, een netwerkverbinding of een andere bron die bytes uitzendt. Laten we een eenvoudig bestand gebruiken dat de volgende gegevens bevat:

Computerprogrammering kan een gedoe zijn. Het is alsof je een verdedigd kasteel probeert te veroveren

De eerste oplossing die we kunnen proberen, is om het bestand regel voor regel handmatig te lezen:

val reader = BufferedReader (inputStream.reader ()) val content = StringBuilder () probeer {var line = reader.readLine () terwijl (regel! = null) {content.append (regel) regel = reader.readLine ()}} eindelijk {reader.close ()}

Ten eerste hebben we de BufferedReader klasse om de InputStream en lees dan totdat er geen regels meer in de stream zijn. Bovendien hebben we de leeslogica omringd door de probeer het eindelijk verklaring aan sluit eindelijk de stroom. Al met al is er veel standaardcode.

Kunnen we het compacter en leesbaarder maken?

Absoluut! In eerste instantie kunnen we het fragment vereenvoudigen door de readText () functie. Het leest de invoerstroom volledig als een Draad. Dienovereenkomstig kunnen we ons fragment als volgt refactoren:

val reader = BufferedReader (inputStream.reader ()) var content: String probeer {content = reader.readText ()} tot slot {reader.close ()}

Dat hebben we echter nog steeds probeer het eindelijk blok. Gelukkig maakt Kotlin het mogelijk om bronnenbeheer op een pseudo-automatische manier af te handelen. Laten we eens kijken naar de volgende coderegels:

val content = inputStream.bufferedReader (). use (BufferedReader :: readText) assertEquals (fileFullContent, content) 

Deze oplossing met één regel ziet er eenvoudig uit, maar er gebeurt veel onder de motorkap. Een belangrijk punt in de bovenstaande code is de aanroep van de gebruik() functie. Deze uitbreidingsfunctie voert een blok uit op een bron die het Afsluitbaar koppel. Eindelijk, wanneer het blok wordt uitgevoerd Kotlin sluit de bron voor ons.

3. Teken stoppen

Tegelijkertijd kan er een geval zijn waarin dat nodig is lees inhoud tot een specifiek personage. Laten we een extensiefunctie definiëren voor de InputStream klasse:

fun InputStream.readUpToChar (stopChar: Char): String {val stringBuilder = StringBuilder () var currentChar = this.read (). toChar () while (currentChar! = stopChar) {stringBuilder.append (currentChar) currentChar = this.read ( ) .toChar () if (this.available () <= 0) {stringBuilder.append (currentChar) break}} return stringBuilder.toString ()}

Deze functie leest bytes uit een invoerstroom totdat een stopteken verschijnt. Tegelijkertijd in orde om de oneindige lus te voorkomen, noemen we de beschikbaar() methode om te controleren of de stream nog gegevens over heeft. Dus als er geen stopteken in een stream staat, wordt een hele stream gelezen.

Aan de andere kant zijn niet alle subklassen van de InputStream klasse bieden een implementatie voor de beschikbaar() methode. Daarom moeten we ervoor zorgen dat de methode correct wordt geïmplementeerd voordat we de extensiefunctie gebruiken.

Laten we teruggaan naar ons voorbeeld en lees tekst tot aan het eerste witruimteteken (‘ ‘):

val content = inputStream.use {it.readUpToChar ('')} assertEquals ("Computer", inhoud) 

Als gevolg hiervan krijgen we de tekst tot aan het stopteken. Vergeet op dezelfde manier niet wikkel het blok met de gebruik() functie om de stream automatisch te sluiten.

4. Conclusie

In dit artikel hebben we gezien hoe u een InputStream naar een Draad in Kotlin. Kotlin biedt een beknopte manier om met datastromen te werken, maar het is altijd de moeite waard om te weten wat er intern aan de hand is.

Zoals gewoonlijk is de implementatie van al deze voorbeelden voltooid op Github.