Scala: Píšeme Iterator wrapper pro InputStream

V tomto článku si ukážeme, jak napsat Iterator wrapper pro InputStream.

Wrappery budou celkem dva. První, který bude data načítat po bytech, a druhý, který je bude načítat pomocí bufferu. Každý z wrapperů bude dědit z traitu Iterator, kde je potřeba implementovat metody next() a hasNext().

Nejdříve si ukážeme celý kód včetně objektu pro jejich vyzkoušení:

import java.io._
 
class ISWrapper(is: InputStream) extends Iterator[Int] {
 
    var value = 0
 
    def next = value
 
    def hasNext = {
	value = is.read
	value != -1
    }
 
}
 
class ISBufferedWrapper(is: InputStream, size: Int) extends Iterator[Array[Byte]] {
 
    var value: Array[Byte] = null
 
    def next = value
 
    def hasNext = {
	val b = new Array[Byte](size)
	val read = is.read(b);
	value = b take read
	read > 0
    }
}
 
object wrapperTest extends Application {
 
    val isw = new ISWrapper(new FileInputStream("file"))
 
    println("ISWrapper:")
    for(ch <- isw) print(ch.toChar)
    println("\n")
 
    println("ISBufferedWrapper:")
    val isbw = new ISBufferedWrapper(new FileInputStream("file"),1000)
    for(ch <- isbw) ch foreach { ch2 => print(ch2.toChar) }
    println()
 
}

Poznámky ke kódu

U prvního wrapperu chceme, aby metoda next() vracela celočíselnou hodnotu. Proto při dědění z traitu Iterator specifikujeme genericky typ jako Int. Analogicky platí totéž pro druhý wrapper – next() bude vracet Array[Byte]:

class ISWrapper(is: InputStream) extends Iterator[Int] {
.
.
class ISBufferedWrapper(is: InputStream, size: Int) extends Iterator[Array[Byte]] {

Metoda hasNext() je volána vždy před přečtením dalšího bytu/pole bytů. Proto při jejím volání již dané data načteme, jejich hodnotu uložíme a rozhodneme, jestli se nacházíme na konci streamu. Při volání metody next() už jenom vrátíme uloženou hodnotu.

def hasNext = {
    value = is.read
    value != -1
}
.
.
def hasNext = {
    val b = new Array[Byte](size)
    val read = is.read(b);
    value = b take read
    read > 0
}
  • Share/Bookmark

Zanechat odpověď