java - 处理在我的代码中抛出 EOFException 的 DataInputStream.readFully 方法的最佳方法

标签 java exception

我正在使用 DataInputStream.readFully 方法,并尝试找出处理此方法中执行的 EOFException 的最佳方法。我收到此日志条目,并且可以使用一些帮助来尝试找出问题所在,因为此异常似乎没有得到处理,并且我的问题陷入了具有相同错误的循环中。任何帮助/指导将不胜感激。谢谢。

    TRACE |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   528 |2013-11-22 11:10:02,311| - Received 2 bytes: 
S
  INFO |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   455 |2013-11-22 11:10:02,312| - Received message, length is 2643
  INFO |     AccSysFNBBT-Socket-1-ReceiveQueuer-1 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   453 |2013-11-22 11:10:03,315| - Waiting for new message.
  WARN |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   483 |2013-11-22 11:10:03,315| - 
java.io.EOFException
    java.io.DataInputStream.readFully(Unknown Source)
    com.sharpbancsystems.ATM.channel.ActiveSocket.blockUntilGetMessageBytes(ActiveSocket.java:462)
    com.sharpbancsystems.ATM.channel.ActiveSocket.blockUntilReceiveMessage(ActiveSocket.java:266)
    com.sharpbancsystems.ATM.channel.ReceiveQueuer.run(ReceiveQueuer.java:113)
    java.lang.Thread.run(Unknown Source)

这是我的代码,发生这种情况:

private byte[] blockUntilGetMessageBytes(final Request request, final ProcessingTimer timer) throws ChannelException {

    byte[] data = null;
    int len;        
    try {
        // have to synchronize on the dataInputStream because the class was designed to have more than one ReceiveQueuer using this method
        synchronized (dataInputStream) {
            LOGGER.info("Waiting for new message.");
            len = blockUntilGetMessageLength();
            LOGGER.info("Received message, length is " + len);

            if (!owningChannel.shouldTerminate) {
                if (len > 0 && len <= 15000) {
                    request.setTimeStampDataFieldAsTimestamp(RequestConstants.SaveDataField.FromStartReceiveTMS);
                    timer.start();
                    data = new byte[len];
                    dataInputStream.readFully(data, 0, len);

                    LOGGER.trace("Full message: " + new String(data));
                    request.setTimeStampDataFieldAsTimestamp(RequestConstants.SaveDataField.FromFinishReceiveTMS);
                    timer.finish();
                    request.setNanosecondDataField(RequestConstants.SaveDataField.FromReceiveNS, timer.nanos());
                    if (channelStats != null) {
                        channelStats.addBytesReceived(data.length + 2); // include the 2 bytes for the length indicator
                        channelStats.increaseReceivedMsgs();
                    }
                } else if (len == 0) {
                    // Should probably log it, but continue
                    LOGGER.info("Empty message received.");
                    throw new ChannelException(getBankID(), "Empty message received");
                } else {
                    throw new ISOException("Invalid receive length: " + len + ".");
                }
            }
        }
        return data;
    } catch (final Exception ex) {
        LOGGER.warn(FormatData.fullStackTrace(ex));
        throw new ChannelException(getChannelID().getNumericId(), this.getClass().getSimpleName().concat(".getMessageBytes()"), ex);
    }
}

protected int blockUntilGetMessageLength() {
    final byte[] b = new byte[2];
    try {
        dataInputStream.readFully(b, 0, 2);
    } catch (final EOFException ex){
        // ***** 20131022 MS - Per Shannon add getNeedReconnect() here. *****
        getNeedReconnect().set(true);
        socket.isConnected();
        // ***** 20131022 MS - Per Shannon this means there was a premature EOF. *****
        if (this.shouldTerminate) {
            return 0;
        } else {
            synchronized (socket) {
                socket.notify();
            }
            LOGGER.warn(FormatData.formatStack(ex));
        }
    } catch (final IOException ex) {
        // ***** 20131022 MS - Per Shannon add getNeedReconnect() here. *****
        getNeedReconnect().set(true);
        socket.isConnected();
        if (this.shouldTerminate) {
            return 0;
        } else {
            synchronized (socket) {
                socket.notify();
            }
            LOGGER.warn(FormatData.formatStack(ex));
            return 0;
        }
    }
    LOGGER.trace("Received 2 bytes: " + new String(b));
    return ((((b[0]) & BYTEMASK) << BYTESHIFT) | ((b[1]) & BYTEMASK));
}

最佳答案

您会得到异常,因为 len 大于您可以从流中读取的字节数。所以显然 blockUntilGetMessageLength(); 返回了一个错误的值。

如果不知道如何计算len,就不可能告诉您如何真正解决这个问题。但无论如何,您可以简单地执行以下操作:

public final int readFully(InputStream in, byte b[], int off, int len) throws IOException {
    if (len < 0)
        throw new IndexOutOfBoundsException();
    int n = 0;
    while (n < len) {
        int count = in.read(b, off + n, len - n);
        if (count < 0)
            break;
        n += count;
    }
    return n;
}

该方法将返回实际读取的字节数。

关于java - 处理在我的代码中抛出 EOFException 的 DataInputStream.readFully 方法的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20195206/

相关文章:

java - Android fatal error "Unable to instantiate Activity"

查询字符串参数的 Java URL 编码

java - 客户端断开连接时线程异常

c++ - 在堆栈展开时使用 RAII 是否安全?

exception - 带有 redux 错误的 React-navigation TabNavigator

Java - 将文件中的整数相加

javascript - "Uncaught SyntaxError: Cannot use import statement outside a module"尝试在 Django 应用程序的 js 文件中导入 vue.js

java - 如何在 Eclipse 启动时重新启用类验证

java - 如何使数组大小取决于文本文件大小?

java - 当类实现相同的接口(interface)时,Lambda 表达式会失败并出现 LambdaConversionException?