Bytes to file, are they miswritten?

喜你入骨 提交于 2019-12-25 08:18:31

问题


Env: Windows 7, java 1.8, default OS encodings

I'm trying to read a byte stream of currency market data from a socket to a file, and then play that file back to simulate the market over a fixed period; however, the file has a few malformed bytes, seemingly at random.

Below, I outline the problem with metacode, where the notation "..." indicates skipped irrelevant or boilerplate code.

Bytes are coming over the socket, and I'm reading them with a non-blockingNIO selector, then writing to disk via BufferedOutputStream:

class SocketReadDiskWrite implements Runnable{
    ...
    blobWriter = new BufferedOutputStream(new FileOutputStream(blobFileName));  
    sc = SocketChannel.open(addr)
    sc.configureBlocking(false);

And then in the run() method, when the selector deems the socket readable,

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

The processData method works fine when reading from a live stream of the market. For example, maybe processData reads a list of currencies and prints them, and the output is,

`EUR.USD.SPOT, EUR.AUD.SPOT, ..<thousands more>.. AUD.CAD.SPOT`

However, if I instead try to play back the captured bytestream (ie. Read in the contents of the file that was just previously created), on occasion, a corrupt symbol appears,

`EUR.USD.SPOT, EUR.AUD.SPOT, ..<thousands more>.. AUD.C@#$@##X`

Looking at the file in notepad++, indeed I find incorrect bytes (blue = correct symbols, red = malformed).

Subsequently, when the application points to the bytefile reader (instead of live market), the app fails at exactly these lines, throwing errors like Invalid symbol: EUR.-XD@#O@#$.

For what it's worth, this is how I playback the file by reading it from disk and streaming to socket:

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

Note, I recently opened a related thread similar thread, but that was in regard to FileChannels, which were actually not the culprit. Figured that discussion had deviated enough to warrant a fresh post.

来源:https://stackoverflow.com/questions/40725665/bytes-to-file-are-they-miswritten

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!