2016-08-13 120 views
1

随着标准的Java java.io.DataInputStream有可能读起来像异类二进制数据:非阻塞读Scala中没有制定

val stream = new DataInputStream(???) 
    val i = stream.readInt() 

    if (i > 5) { 
    val string = stream.readUTF() 
    ??? 
    } else { 
    val long = stream.readLong() 
    ??? 
    } 

它的不同之处在于它消耗整个主题确定,所以不会在高负载的服务器有用。

是否有可能找到/制作一些Scala的API,它看起来像这样但是非阻塞?

当然有一个Netty中的ByteBuf秒,但他们需要制定像LengthFieldBasedFrameDecoder,以确保所有数据已收到之前,我将开始读它,并在我的情况下进入的数据包不包括长度,所以它不是在完全解析数据包之前可能知道数据包的长度。对于这种情况确实存在ReplayingDecoder,但它的表现并不是很有希望。

解决方案我想上包裹Netty的处理程序是这样的:

trait NonBlockingReader { 

    def readInt: Future[Int] 

    def readUTF: Future[String] 

    def readLong: Future[Long] 

    //... 

    } 

然后它可以像使用:

val source: NonBlockingReader = ??? 

    val someResult: Future[Any] = for (
    i <- source.readInt; 
    r <- if (i > 6) source.readUTF else source.readLong 
) yield r 

这是很方便的,好看的,并没有按”不需要构图,但我想知道它不是一个开销,我不是在重新发明轮子吗?

回答

0

Scala没有提供非阻塞文件IO的显式API,但是普通的Java API在这些情况下正好适用。您应该查看使用java.nio.channels.AsynchronousFileChannel或Java NIO Api。

+0

'java.nio。*'特别是'java.nio.channels.AsynchronousFileChannel'是低级API。我正在谈论高级别的API,我不应该在乎缓冲区和读写索引 - 就像我在'DataInputStream'中所做的那样读取Ints,Longs,Strings等等' –

+0

'scala中的'Futures'怎么样。并发“,它不提供像readInt,readLong等方法,但是你可以为这个方法编写自己的包装器。第二种方法是利用'akka.stream.io',但它可以强制你使用缓冲区。 – pacman

+0

正如我所见,阿卡流也需要框架。 –