// 问题八:
// 在java.io类库中,你可以通过BufferedInputStream修饰器来给输入流增加缓冲机制。
// 用特质来重新实现缓冲。简单起见, 重写read方法
import java.io.{IOException, InputStream}
trait BufferedInputStreamLike {
this: InputStream =>
protected val bufSize: Int = BufferedInputStreamLike.DEFAULT_BUFFER_SIZE
protected var pos: Int = 0
protected var count: Int = 0
protected val buf = new Array[Byte](bufSize)
override defread(): Int = synchronized{
if (pos >= count) {
fill()
if (pos >= count)
return -1
}
val buffer = getBufIfOpen
pos += 1
buffer(pos - 1)
}
private deffill(): Unit = {
count = 0
pos = 0
val n = this.read(getBufIfOpen, 0, buf.length)
if (n > 0)
count += n
}
private defgetBufIfOpen: Array[Byte] = {
if (buf == null) new IOException("Stream closed")
buf
}
}
object BufferedInputStreamLike {
val DEFAULT_BUFFER_SIZE = 8192
}
classTraitTestextendsFunSuitewithBeforeAndAfter {
before {
println("---------")
}
test("BufferedInputStreamLike") {
var start = System.nanoTime()
val fileInputStream = new FileInputStream("/home/jack/top")
for (i <- 1 to 100000) fileInputStream.read()
var end = System.nanoTime()
println(s"Without\tBufferedInputStreamLike, cost time:${end -start} ns" )
fileInputStream.close()
// Part II
start = System.nanoTime()
val bufferedInputStream: FileInputStream with BufferedInputStreamLike = new {val bufferSize = 100000} with FileInputStream("/home/jack/top") with BufferedInputStreamLike
for (i <- 1 to 100000) bufferedInputStream.read()
end = System.nanoTime()
println(s"With\tBufferedInputStreamLike, cost time:${end -start} ns" )
bufferedInputStream.close()
}
// sbt shell // testOnly Trai* -- -z "InputStreamLike"/*
---------
Without BufferedInputStreamLike, cost time:54517999 ns
With BufferedInputStreamLike, cost time:19849703 ns
[info] TraitTest:
[info] - BufferedInputStreamLike
[info] Run completed in 191 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 0 s, completed Aug 2, 2018 5:01:07 PM
*/
问题九:使用本章的日志生成器特质,给前一个练习中的方案添加日志功能,要求体现出缓冲的效果。
package example.traits
trait Logger {
deflog(msg: String): Unit ={}
}