环境:Windows 7,java 1.8,默认操作系统编码
我试图从套接字到文件读取货币市场数据的字节流,然后播放该文件以在固定的时间段内模拟市场;但是,该文件有一些格式错误的字节,似乎是随机的。
下面,我概述了元代码的问题,其中符号" ..."表示跳过不相关或样板代码。
字节来自套接字,我用非阻塞 NIO
选择器读取它们,然后通过BufferedOutputStream
写入磁盘:
class SocketReadDiskWrite implements Runnable{
...
blobWriter = new BufferedOutputStream(new FileOutputStream(blobFileName));
sc = SocketChannel.open(addr)
sc.configureBlocking(false);
然后在run()
方法中,当选择器认为套接字可读时,
public void run(){
...
while(keyIterator.hasNext())
{
SelectionKey key = keyIterator.next();
if (key.isReadable()) {
if(bytesRead == -1)
{
connected = false;
logger.warn("no bytes to read");
break;
}
readBuffer.flip();
// Write bytes from socket to file, then rewind and process data
while (readBuffer.hasRemaining()){
byte[] b = new byte[readBuffer.remaining()];
readBuffer.get(b);
blobWriter.write(b);
}
readBuffer.rewind();
processData(readBuffer); //<-- Further processing
...
}
从市场的实时流中读取时,processData
方法可以正常工作。例如,processData可能会读取货币列表并打印它们,输出为
`EUR.USD.SPOT, EUR.AUD.SPOT, ..<thousands more>.. AUD.CAD.SPOT`
但是,如果我试图回放捕获的字节流(即读取之前创建的文件的内容),有时会出现损坏的符号,
`EUR.USD.SPOT, EUR.AUD.SPOT, ..<thousands more>.. AUD.C@#$@##X`
在notepad ++中查看文件,确实找到了错误的字节(蓝色=正确的符号,红色=格式错误)。
随后,当应用程序指向字节文件阅读器(而不是实时市场)时,应用程序会在这些行中失败,抛出Invalid symbol: EUR.-XD@#O@#$
之类的错误。
对于它的价值,这是我通过从磁盘读取文件并流式传输到套接字来播放文件的方式:
class FilePlayer implements runnable (Socket clientSocket) {
clientWriter= clientSocket.getOutputStream();
blobReader = new FileInputStream(blobFileName);
byte[] dataArray = new byte[1024]; //<-- Store 1024 bytes data at a time
...
}
public void run() {
while(true){
blobReader.read(dataArray); //<-- Read 1024 bytes of data from disk
clientWriter.write(dataArray); //<-- Write 1024 bytes of data to socket
}
}
注意,我最近打开了一个related thread类似的帖子,但这与FileChannels
有关,实际上并不是罪魁祸首。认为讨论偏差足以保证一个新的帖子。