2016-11-18 62 views
0

我的目标是从套接字读取字节流到文件中,然后稍后作为我的应用程序的测试工具回放。在将字节写入磁盘的某个地方,一个字节会被错误地写入,看起来是随机的。Java窗口将字节写入文件,有些不正确

我的作家是这样的:

blobWriter = new BufferedOutputStream(new FileOutputStream(blobFileName)); 
blobChannel = Channels.newChannel(blobWriter); 

我使用的是blobChannel,这样我可以从一个ByteBuffer直接写。在插座的每个读,我简单地缓冲传递给作家:

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> 
} 

当饲料直播,节目流程读入的记录,他们没有损坏。对每条消息说,它输出一个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) 

请注意腐败符号

最奇怪的是,它会处理成千上万的消息具有相同的符号和其他领域没有问题,但然后莫名其妙地一个消息被损坏。并不总是符号字段是不正确的,有时orderId是错误的等...

我怀疑blobWriter有时是错误写入。我的操作系统(Windows 7)可以做些什么奇怪的事情吗?我检查了notepad++中保存到磁盘的字节流,实际上它显示了不正确的字节,所以错误必须在文件写入器中,而不是在我的播放机制中。此外,如果主应用程序本身有问题,它应该误读活动提要上的字节;它没有。

有谁知道什么可能会出错?

+0

输出显示在哪里? –

+0

哪个输出具体? –

+0

你提到的'处理后的输出'。 –

回答

0

貌似WritableByteChannel的Javadoc试图警告我:

除非另有规定,一个写操作只会 写所有的R请求的字节后返回。根据它们的状态,某些类型的通道 可能只写入一些字节或可能根本没有。处于非阻塞模式的套接字通道(例如 示例)无法写入比套接字的 输出缓冲区中的空闲字节更多的字节。

事实上,套接字通道处于非阻塞模式。我对此进行了描述,每200次读取一次就不同步。看起来我的频道正在写更多的字节,我的读者实际上是从缓冲区读取的。

Another SO thread offers more information.

什么终于为我工作是复制在每个字节组读,而不是用流。这可能不是性能最佳的,但至少它不会导致错误的数据:

if (readBuffer.hasRemaining()){ 
    byte[] b = new byte[readBuffer.remaining()] 
    readBuffer.get(b) 
    blobWriter.write(b) 
} 
+0

复制到一个字节数组不应该是必要的。一个简单的'while(readBuffer.remaining()> 0)blobWriter.write(readBuffer);'应该可以。但是,如果我正确地理解了这一点,那么您确实经历过一个案例,您链接到的问题的答案是*“不,它不会始终写入整个缓冲区” - 这是正确的吗? – Marco13

+0

感谢Marco,我相信。 –

+0

我试过这个Marco,但仍然有误读。我打开了一个单独的线程,因为我有同样的问题,我不再使用频道:http://stackoverflow.com/questions/40725665/java-bytes-to-file-are-they-miswritten –