Java窗口将字节写入文件,有些不正确

时间:2016-11-18 19:17:52

标签: java sockets io buffer nio

我的目标是从套接字读取一个字节流到一个文件中,然后在以后播放它作为我的应用程序的测试工具。在将字节写入磁盘的某处,一个字节将被错误地写入,似乎是随机的。

我的作家看起来像这样:

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++中保存到磁盘的字节流,实际上它显示的字节不正确,因此错误必须在文件编写器中,而不是在我的播放机制中。此外,如果主应用程序本身是错误的,它应该误读实时订阅源上的字节;它没有。

有谁知道可能出现的问题?

1 个答案:

答案 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)
}