我的目标是从套接字读取一个字节流到一个文件中,然后在以后播放它作为我的应用程序的测试工具。在将字节写入磁盘的某处,一个字节将被错误地写入,似乎是随机的。
我的作家看起来像这样:
blobWriter = new BufferedOutputStream(new FileOutputStream(blobFileName));
blobChannel = Channels.newChannel(blobWriter);
我正在使用blobChannel
,以便我可以直接从ByteBuffer
写信。在每次读取套接字时,我只是将缓冲区传递给writer:
if (key.isReadable()) {
final int bytesRead= socketChannel.read(readBuffer);
if(bytesRead == -1)
{
logger.warn("no bytes to read");
break;
}
readBuffer.flip();
blobChannel.write(readBuffer);
...
<continue to process data>
}
当Feed处于活动状态时,程序会读取记录,并且它们没有损坏。对每条消息说,它输出一个由7个字段组成的元组。例如,其中之一是:
(tupleid=0,msgType=110,feedId=225,venueId=30,orderId=160,symbol="CHF.NOK.SPOT",venueTime=44417979)
当代替与市场的实时连接时,我将应用程序挂钩到从磁盘播放相同数据的读取器,处理后的输出变得混乱:
(tupleid=0,msgType=110,feedId=225,venueId=30,orderId=160,symbol="CHF.-�ûnX",venueTime=44417979)
注意损坏的符号。
最奇怪的是,它将使用相同的符号和其他字段处理数千条消息没有问题,但是后来莫名其妙地一条消息被破坏了。它并不总是符号字段不正确,有时订单ID错误等...
我怀疑blobWriter
有时会被误写。我的操作系统(Windows 7)可以做一些时髦的事吗?我已经检查了notepad++
中保存到磁盘的字节流,实际上它显示的字节不正确,因此错误必须在文件编写器中,而不是在我的播放机制中。此外,如果主应用程序本身是错误的,它应该误读实时订阅源上的字节;它没有。
有谁知道可能出现的问题?
答案 0 :(得分:0)
看起来WritableByteChannel
javaDoc试图警告我:
除非另有说明,否则写操作将仅在返回之后返回 写入所有r请求的字节。某些类型的频道, 根据它们的状态,可能只写一些字节或 可能根本没有。非阻塞模式下的套接字通道,用于 例如,无法写入比套接字中的空闲字节多的字节 输出缓冲区。
确实套接字通道处于非阻塞模式。我对此进行了分析,每200个读取中就有一个不同步。看起来我的频道正在写更多的字节,我的读者实际上是从缓冲区读取的。
Another SO thread offers more information.
最终对我有用的是在每次读取时复制bytearray而不是使用流。这可能不是性能最佳,但至少它不会导致错误的数据:
if (readBuffer.hasRemaining()){
byte[] b = new byte[readBuffer.remaining()]
readBuffer.get(b)
blobWriter.write(b)
}